git更新提交到仓库

1、前言

假设当前已经git clone了一个仓库项目,并从项目仓库中获得了所有文件的工作拷贝,那么,如何对这些文件进行修改,完成了一定阶段的修改后,提交本次更新到仓库?

工作目录下的每个文件都处于两种状态:未跟踪和已跟踪状态,已跟踪的文件是指哪些已经纳入版本控制的文件,上一次快照中有这些文件的记录,在目录下工作一段时间后,文件的状态可能处于未修改、已修改或者处于暂存区。工作目录中除了已跟踪的文件以外,其它的文件属于未跟踪状态,它们既不存在于上一次记录的快照中,也没有放入暂存区。当我们初次git clone某个仓库时,工作目录下的所有文件都属于已跟踪状态,并处于文件未修改状态。

当我们编辑和修改某些文件后,由于自上次提交之后对这些文件进行了修改,git会将这些文件标识为已修改文件,在工作过程中,我们还会逐步将这些修改过的文件放入暂存区,然后提交所有暂存了的修改,如此反复,使用git操作时,文件的生命周期如下所示:

2、查看工作目录的文件状态

想要查看当前工作目录的文件状态,可以使用下面的命令:

$ git status

如果我们在git clone某个仓库后,马上在当前的工作目录下执行该命令,查看当前的文件状态,执行结果输出如下:

该输出结果表明,当前工作目录是相当干净的,换句话来说,也就是所有已跟踪文件在上次提交后都没有被修改过,另外,上面的结果还表示了,当前工作目录并没有出现任何处于未跟踪状态的新文件,如果有未跟踪状态的新文件,git会列举出来,最后,输出信息还表明了,当前所在的分支为"master",为默认分支,并告诉我们当前的分支同远程服务器上对应的分支没有发生偏离。

接下来,在项目当中创建一个新的app.c文件,并在文件里面输入一些C代码,如果在此之前,项目中并没有存在该文件的话,这时候,使用git status命令进行查看,将会看到一个新的未跟踪状态文件,如下:

创建新的app.c文件:

$ cd myGitTest
$ touch app.c
$ vim app.c

在app.c文件在输入下面的内容,然后保存退出:

新的app.c文件创建并编辑后,再次使用下面命令查看当前文件的状态:

$ git status

新的文件状态输出结果,如下所示:

在上面的文件状态输出结果可以看到,新创建的app.c文件出现在了"Untracked files"行下面,说明新创建的app.c文件目前处于未跟踪状态。未跟踪的文件说明在之前的快照中并没有这些文件,git不会自动将这些文件纳入跟踪范围,这样的处理,可以让我们不必担心生成的二进制文件或者不想被跟踪的文件包含进来,但是,在上面的新创建app.c文件,我们是需要跟踪管理的。

3、跟踪管理新文件

在项目仓库中,如果我们需要开始跟踪管理一个新的文件,可以使用下面的命令:

$ git add <file>

例如,在上面举的例子当中,我们新创建了一个app.c文件,从git status输出的文件状态结果可以知道,新创建的app.c文件处于未跟踪状态,因此,可以使用下面的命令,开始跟踪管理app.c文件:

$ git add app.c

此时,新创建的app.c已经处于跟踪状态了,这个时候,我们再使用下面命令查看当前文件的状态:

$ git status

命令的执行结果如下所示:

从上面的输出结果可以看到,当我们使用git add命令对新创建的app.c文件进行跟踪管理后,app.c的文件状态从未跟踪状态转变为了跟踪状态,并且,目前app.c文件处于暂存状态,此外,我们可以从输出结果可以看到,新创建的app.c文件被列举在"Changes to be committed"行下,如果,这个时候进行提交的话,那么新创建的app.c文件此时此刻的版本将会留存在历史记录中。

另一个方面,git add命令使用文件或目录作为参数,如果参数是目录的话,将递归地跟踪管理到该目录下的所有文件。

4、暂存已修改的文件

在上面的例子基础下,接下来,我们对当前工作目录下已跟踪的文件README.md进行编辑修改,修改完成后,使用git status命令查看当前的文件状态:

$ vim README.md
$ git status

使用vim编辑器对README.md文件进行修改后,执行git status命令后,文件状态的输出结果如下所示:

从上面的输出结果可以看到,我们编辑修改过后的文件README.md,被列举在了"Changes not staged for commit"行下面,说明已跟踪的文件的内容已经发生了改变,但是还没有暂存这次内容更新,也就是对README.md文件的修改,我们并没有暂存下来。

如果我们想暂存这次README.md文件内容的更新,可以使用下面的命令:

$ git add README.md

git add命令是一个多功能命令,我们可以用它开始跟踪新创建的文件,或者将已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标识为已解决状态等,在这次操作当中,该命令理解为"添加新内容到下一次提交中"而不是"将一个文件添加到项目中",在上面的命令执行后,编辑修改过的文件README.md将被放到暂存区。

这时候,我们再使用下面的命令查看当前文件的状态:

$ git status

命令执行后,输出的结果如下所示:

上面的输出结果表明,现在两个文件app.c和README.md都已经被暂存起来,下次提交的时候将会一并记录到仓库中。

假如此时,我们需要在文件README.md中编辑并添加新的内容,然后再用git status进行文件的状态查看:

$ vim README.md
$ git status

上面的命令执行后,工作目录的文件状态如下所示:

从上面的输出结果可以看到,文件README.md同时出现在了暂存区和非暂存区,为什么会出现这样的结果呢?实际上,git只不过暂存了前面运行了git add命令时的版本,如果现在提交的话,此时README.md的版本是最后一次运行git add命令时的哪个版本,而不是运行git commit命令时,当前工作目录的版本,因此,我们需要注意的是,运行了git add命令暂存后,再次对暂存区的文件进行编辑修改,一定要再次运行git add命令把最新的文件版本暂存起来。

接下来,我们使用下面的命令将再次编辑修改的README.md文件暂存起来,并查看文件状态是否发生改变:

$ git add README.md
$ git status

命令执行后,输出结果如下所示:

从输出结果可以看到,两个文件都处于暂存区了,包括再次对README.md文件编辑修改的内容也再次被暂存起来了,这正是我们想要的结果。

5、查看已暂存和未暂存的修改

在上面举的例子当中,我们使用git status命令可以查看当前工作目录的文件状态,命令运行后,从输出结果可以看到我们未跟踪哪些文件、修改了哪些文件和暂存了哪些修改,但是这个命令是模糊的,我们并看不到具体修改了文件哪些地方,如果我们想查看已经暂存和未暂存的修改,可以使用下面的命令:

$ git diff

上面的命令将通过文件补丁的形式显示文件哪些地方进行了修改,非常详细。

接下来,基于上面的例子,假如我们再次编辑修改已经暂存的文件README.md,在文件的最后,添加一些版本信息:

README.md文件修改之前,如下:

README.md文件修改之后,如下:

从上面的文件修改前后对比,可以知道,我们对README.md文件只是简单增添了12和13这两行,12行为空行,13行添加了"Version:1.0"字符串。

接下来,我们先不要去暂存文件README.md的内容修改,运行下面命令查看当前文件状态:

$ git status

命令执行完成后,输出结果如下所示:

从上面的输出结果可以看到,被修改过后的README.md文件,再次被列举到"Changes not staged for commit"行下面,说明此时的内容修改还并没有暂存起来。

接下来,我们需要查看还没有暂存的文件修改了哪些部分,也就是刚刚修改的README.md文件,不加任何参数,直接输入下面的命令:

$ git diff

命令执行后,输出结果如下:

在上面的输出显示,重点是黄色圈出的地方,显示为绿色的地方,也就是下面的两行:

+
+Version:1.0

在上面列出的两行中,行的前面都带有'+'字符,说明是文件新添加的内容,在上面文件修改对比的时候,也说过了,我们就是增加了这两行。

需要注意的是,git diff命令本身只显示文件没有暂存的内容修改,而不是自上次提交以来所做的所有改动,因此,当我们一下子暂存了所有修改更新过的文件后,运行git diff命令却什么都没有输出,就是因为这个原因。

接下来,我们可以使用下面的命令来查看文件已经暂存起来的内容修改(--staged和--cached参数是一样的效果):

$ git diff --staged
or
$ git diff --cached

命令执行后,输出如下所示:

从上面的输出结果来看,分别对比了暂存的两个文件:新创建的app.c文件和编辑修改的README.md文件,其中,红色的内容表示删除,绿色的内容表示添加的,文件被修改过的地方都很详细地显示出来了。

6、提交已暂存的更新

基于上面的例子,现在,项目的暂存区域已经准备妥当了,就可以使用命令进行更新提交了,但是在此之前,我们一定要确认还有没有修改过的文件或者新创建的文件没有被git add过,否则的话,提交的时候并不会去记录这些没有暂存的变化,这些修改过的文件将只留在本地磁盘中,因此,我们要切记,每次提交时,需要先用git status查看,要提交的更新是否都已暂存起来了,如果输出显示还有没有暂存起来的文件,则需要使用git add命令进行暂存,再运行提交命令,如下:

$ git status
$ git add .
$ git commit

这种方式的提交将会启动文本编辑器以便输入本次提交的说明,默认会启用shell的环境变量$EDITOR所指定的文本编辑软件,一般是vim或者emacs,可以使用git config命令进行修改。

例如,提交的时候会类似显示下面的内容:

从vim编辑器显示的内容看,默认的提交信息包含了最后一次使用git status命令的输出内容,放在了注释的地方,此外,开头还空出了一行,用于我们输入提交说明,当我们没有输入任何的话,退出编辑器,本次提交将会中断,也就是提交将不会成功。

另外,我们也可以在git commit提交的时候添加-m选项,将提交的信息和命令放在一同一行,如下提交的命令:

$ git status
$ git add .
$ git commit -m "create app.c and modified files"

提交命令执行后,输出如下所示:

从上面的输出结果可以看到,我们已经成功创建了一个提交,此外,从提交的输出信息看,还能知道是在哪个分支进行提交的,本次提交的完整SHA-1校验和是什么,本次提交的校验和为4a4d50d,还有就是,本次提交修改了多少个文件,添加了多少行,删除了多少行,非常详细。

需要注意的是,提交时记录的是放在暂存区的文件的快照,任何还没有暂存的仍然保持已修改的状态,我们可以在下次提交时纳入版本管理,每次运行提交操作,都是对项目作一次快照,下次可以回到这个状态,或者对其进行比较。

7、提交时跳过使用暂存区域

在上面提交的例子中,我们知道,使用暂存区的方式进行提交,能够精心准备需要提交的细节,但是有时候却显得比较繁琐,基于此,git提供了一个跳过使用暂存区域的方式,当我们使用git commit命令进行提交的时候,加上-a选项即可,这时候,git会自动把所有已经跟踪过的文件暂存起来,并一起进行提交,从而跳过了git add这个步骤,比较方便。

基于上面的例子,将刚刚提交的内容git push到远程服务器后,再次对app.c文件进行修改,然后使用git status进行文件状态查看,如下:

$ git push origin master
$ vim app.c
$ git status

输出如下所示:

从输出结果可以看到,此时app.c文件被列举在了"Changes not staged for commit"这行,说明此时,app.c文件的内容发生了变化,但是此次变化并没有被暂存起来,接下来,我们运行下面的命令进行提交:

$ git commit -a -m "modified app.c"

命令执行完成后,输出如下:

从输出结果看,本次提交成功了,并且得到了SHA-1校验和为aac6bfb,所以,在使用git commit命令进行提交时,使用-a参数,可以直接跳过使用暂存区,也就是git add命令。

8、文件移除

要想从git仓库中移除文件,就必须从已跟踪的文件清单中进行文件移除,准确地说,应该是从暂存区域中移除文件,然后进行更新提交,对于此操作,我们可以使用下面的命令进行:

$ git rm <file>

命令执行后,将从工作目录中删除指定的文件,并且,被删除的文件也不会再出现在未跟踪的文件清单中了。

如果在使用git进行版本管理的时候,只是简单地使用rm命令从工作目录删除文件,当我们运行git status命令查看文件状态时,将会看到被删除的文件被列举在"Changes not staged for commit"该行下面,也就是处于未暂存状态,如下:

基于上面git clone的项目,对仓库的hello.c文件进行修改,并使用git add命令将其添加到暂存区,然后使用rm命令直接删除文件,看看会出现什么情况,命令如下:

$ cd myGitTest
$ vim hello.c
$ git add .
$ git stauts

命令执行后,输出如下:

从上图可以看到,文件hello.c修改的内容已经被暂存起来了,接下来,直接使用rm命令删除文件,并使用git status查看当前文件状态,命令如下:

$ rm -rf hello.c
$ git status

命令执行后,输出如下:

从上面的输出结果可以看到,对于hello.c文件,刚刚修改的内容还留在暂存区域,并没有从跟踪清单中除去,hello.c文件同时被列举在了"Changes not staged for commit"该行下面,这时候,可以使用git add命令进行暂存,下次提交时,该文件将不再纳入版本管理。

接下来,我们来看看使用git rm命令进行删除的效果,首先,我们新创建一个文件test.txt,然后使用git add命令纳入版本管理,再使用git status进行文件状态查看,命令如下:

$ touch test.txt
$ git add test.txt
$ git status

命令执行后,结果输出如下:

从输出结果可以知道,新创建的文件test.txt被列举在了"Changes to be committed"行下面,也就是,此文件已经位于暂存区域了,我们可以直接进行提交,但是本次我们不直接提交,而是使用git rm命令对其进行暂存区移除,并从磁盘中进行删除,命令如下:

$ git rm -f test.txt
$ git status

输出结果如下:

从上面的输出结果可以看到,处于暂存区域的hello.c已经被移除了,并且该文件也不会留在了本地磁盘,在下次提交时,并不会再纳入版本管理了,对于已经存在暂存区域的文件,删除的话需要使用-f选项,这是git的一种安全特性,防止我们误删还没有添加到快照的数据,这样的数据不能再被git恢复。

另外一种情况就是,我们想把文件从git仓库中移除,也就是从暂存区域中移除,但是仍然希望将文件留在本地磁盘中,例如,当我们还没有添加.gitignore文件时,不小编译产生了一堆*.o文件,如果这些文件被添加到暂存区域时,这个做法将会比较有用。

接下来,继续基于上面的例子进行讲解,此时新创建的文件test.txt处于暂存区域,使用git status查看文件状态,如下所示:

接下来,我们要将处于暂存区域的test.txt文件进行移除,但是文件还需要留在本地磁盘,可以使用下面的命令:

$ git rm --cached test.txt
$ git status

命令执行后,输出如下:

从输出结果可以看到,新创建的test.txt文件已经从暂存区进行移除了,并被列举在了"Untracked files"该行下面,说明此时文件仍然留在本地磁盘中,并处于未跟踪的状态。

9、文件移动和重命名

和其它的版本控制管理系统不一样,git并不会显示跟踪文件移动操作,如果在git中重命名了某个文件,仓库中存储的元数据并不会体现出是一次改名操作,不过,git会推断出究竟发了什么操作。

当我们需要在git中对文件改名时,可以使用下面的命令进行操作:

$ git mv old_name new_name

基于上面的例子,现在,我们需要对当前工作目录下的README.md文件重命名为README,然后查看当前的文件状态,命令如下:

$ cd myGitTest
$ git mv README.md README
$ git status

命令执行后,输出如下:

从输出结果可以知道,README.md文件已经成功被改名,并且改名后的文件被列举在了"Changes to be committed"行下面,表示我们的修改已经处于暂存区了,可以进行提交了。

其实,当我们在项目中运行git mv命令时相当于运行了下面的个命令:

$ mv README.md README
$ git rm README.md
$ git add README

当我们分开使用这些命令时,git也能够意识到这是一次文件改名操作,所以不管哪种方式,结果都是一样的。

原文地址:https://www.cnblogs.com/Cqlismy/p/12193209.html