Git操作原理

参考文档:http://marklodato.github.io/visual-git-guide/index-en.html

git help

当不太明白各种command的意思时,可以使用git help <command>查看git操作的详细信息。

一、基本操作

  • git add files :将files(在当前的修改状态)复制到stage存区
  • git commit:对暂存区进行一次快照最为一次commit
  • git reset -- files :回退files。
    • git reset --mixed:此为默认方式,不带任何参数的git reset,这种方式,会回退到某个版本,只保留源码,回退commit和index信息
    • git reset --soft:回退到某个版本,只回退了commit的信息(即取消了commit的操作),不会恢复到index file一级。如果还要提交,直接commit即可。
    • git reset  --hard:彻底回退到某个版本,工作目录也会变为上一个版本的内容,此命令 慎用!
  • git revert xxx
           revert与reset的区别在于,revert是将xxx的commit的操作逆向执行一次,重新生成一个新的commit A。(例如,xxx是删除了一行代码:var result = null;而revert就是在相同的位置再加上一行代码:var result = null)。

                  而且commit XXX并没有被删除!只是当前branch的HEAD指向新的commit A而已。这是与reset彻底删除commit XXX的根本区别。

  • git checkout -- files :从暂存区复制文件到工作目录,同时工作目录中未commit的changes会被抛弃。

You can use git reset -pgit checkout -p, or git add -p instead of (or in addition to) specifying particular files to interactively choose which hunks copy.

It is also possible to jump over the stage and check out files directly from the history or commit files without staging first.

  • git commit -a :相当于执行“git add .”,然后git commit。
  • git commit files :?creates a new commit containing the contents of the latest commit, plus a snapshot of files taken from the working directory. Additionally, files are copied to the stage.
  • git checkout HEAD -- files :将最新的commit同步到暂存区和工作目录

常规操作

  • commits用标示为5个字符的绿框表示,他们分别指向其父级commit;
  • 分支以橘色方框表示,他们指向特定的commit;
  • 指针HEAD指向当前工作分支;

图中最新的commit是标示为ed489的commit,当前分支为master分支指向了ed489的commit,而另一个分支maint指向祖先commita47c3。

命令细化

git commit --amend

 git commit --amend:当在执行commit时之后发现此次commit的内容有错误,此时我们需要在工作目录订正这个错误并将他更新到上次含有error的commit中(创建一个新的commit,他和当前的commit指向同一个父级,之后当前的commit被抛弃)。

Checkout

checkout命令可用于从commit链中或暂存区中复制文件到工作目录,并可以选择切换分支。

1、从commit链中或暂存区中复制文件到工作目录

  • 当给定文件名时,git会从给定的commit中复制他并同步到暂存区和工作目录。
  • 此操作不会产生新的commit,不会改变当前操作分支。

例如: git checkout HEAD~ foo.c 

从当前commit的父commit从复制foo.c 文件,同步到工作目录和暂存区。
2、切换分支
git chekout + 分支名
HEAD指向指定分支,然后暂存区和工作目录也会随之匹配到新切换到那个分支的commit(a47c3)。commit(a47c3)的所有文件都将被复制,旧commit (ed489)所有与commit(a47c3)不同的地方都被抛弃,相同的方法被保留。
???当切分支时上一个分支上的工作目录change了,没有commit,git checkout 到新分支时,发现新分支的working dir 带着上一个分支没有commit的change.

Merge

一次merge会生成一个合并其他commits的changes新的commit。在merge之前,暂存区必须与当前的commit同步。

  • 其他commits(要merge过来的)是当前commit的祖先级commit。
  • 当前commit是其他commit(要merge过来的)的祖先级commit。
  • A merge creates a new commit that incorporates changes from other commits. Before merging, the stage must match the current commit. The trivial case is if the other commit is an ancestor of the current commit, in which case nothing is done. The next most simple is if the current commit is an ancestor of the other commit. This results in a fast-forward merge. The reference is simply moved, and then the new commit is checked out.

当前commit是其他commit(要merge过来的)的祖先级commit。

其他commits(要merge过来的)是当前commit的祖先级commit。

Otherwise, a "real" merge must occur. You can choose other strategies, but the default is to perform a "recursive" merge, which basically takes the current commit (ed489 below), the other commit (33104), and their common ancestor (b325c), and performs a three-way merge. The result is saved to the working directory and the stage, and then a commit occurs, with an extra parent (33104) for the new commit.

我的理解:将current commit (ed489 below), the other commit (33104)与common ancestor (b325c)三次commit进行合并,合并的结果会保存到working directory与stage,然后产生新的commit。

 

posted @ 2017-07-27 19:40  月上柳梢头,  Views(146)  Comments(0)    收藏  举报