Everything about Git

注释:本文中,中括号内参数表示可选参数,尖括号内参数表示必选参数。SHA-1值可以是commit的SHA-1值,HEAD[~|^]或者branch名字,因为HEAD和branch名字的SHA-1值都被git所记录。

一般规则

从远端代码仓库中下载项目

git clone

 

在master分支的基础上新建自己的branch,并跳到该branch上:

git checkout -b [origin/master]

 

在该branch上改好代码并commit:

git commit -a -m “”

A.

跳回到master分支上,并merge:

git checkout master; git merge

可以选择性地删掉之前的branch: 

git branch -d

B.

在该branch上,使用rebase: 

git rebase origin/master

rebase使得代码历史看上去线性化延续,而不会出现很多分支

 

在提交自己的commit至remote repository前,必须保证当前本地的repository和remote repository一致。保证两端repository一致的命令:

git fetch origin

 

若要在本地新建新的git repository,只要在该project的根目录下输入

git init

 

符号

下述commit可以为SHA-1代码或HEAD。

commit^ 该commit最近的祖先

commit^ 该commit最近的第几个祖先,只在分支交汇处有用,因为此时一个commit有多个祖先

commit~ 该commit最近的祖先

commit~ 该commit最近的num个祖先,若碰到分支交汇,总是选取第一个祖先

^branch  该branch不可达的所有commit,等价于“–not branch”

..和…查看log中的用法

 

本地

查看所有分支,包括远端和本地:

git branch -a

 

查看远端分支

git branch -r

 

在某一个commit上新建分支:

git branch

 

查看最近一次的commit修改了哪些内容?

git diff HEAD^ HEAD

注:“HEAD^”指代最近一次的commit

 

查看任何一次的commit相比于HEAD,修改了哪些内容?

git diff commit_id HEAD

 

未提交本次commit前,查看当前已经修改了哪些内容?

git diff                      (若修改未staged)

git diff –staged            (若修改已经staged)

 

对某个文件名重命名后将其staged:

git mv <原来的名字> <新的名字> 

 

将某个文件移除出index tree,但并不在磁盘上删除

git rm –cached

 

查看当前git repo 跟踪的所有文件:

git ls-file

 

将所有文件添加至stage area:

git add .

 

切换至别的分支(即将HEAD移至另一个分支上):

git checkout

 

将已经修改的文件复原(即将modified的文件复原):

git checkout —

 

在下一个commit提交之前,清除所有unstaged文件,恢复到上一个commit的snapshot:

git checkout — .                                   (恢复所有unstaged文件至上一个commit)

git checkout [–]                   (恢复单个unstaged文件至上一个commit,
“–”可加可不加)

 

在还没commit前取消merge,恢复到merge前的样子:

git reset –merge

 

将已经staged的文件unstage:

git reset HEAD

 

将HEAD移至之前的某个commit,删除该commit之后的所有commit:

git reset HEAD –hard

 

故撤销上次commit后本地的所有修改可以使用:

git reset –hard HEAD

 

修改最近一次的commit:

git commit –amend [-m ]

例如:

git commit -m “initial commit”

git add forgotten file

git commit –amend

 

查看Git本地Repository的容量,文件大小:

git count-objects -v

as

loose object: 原始文件的存放格式,未被压缩

当运行“git gc”或将本地的repository push到远端repository时,git会自动将之前版本的代码(即之前的loose object)统一打包到一个名为packfile的二进制文件中。packfile文件仅记录之前版本的代码与当前代码的区别,这样就大大缩小了之前的代码占用体积。

size-pack: 整个repository压缩后的最小体积

 

需要纵览性地查看较多commit记录:

git log –pretty=oneline

 

需要详细地查看每个commit记录:

git log -p –stat –graph [-]

注:[-]中num表示你想显示的最新的commit条目个数,若不指定该参数,将会显示所有commit条目

 

查看各分支走向,以及所有commit,并以图形化显示:

git log –graph –all –decorate –pretty=oneline

 

查看某个branch2中branch1不可达的commit(以下三个等价):

git log <branch1_name>..<branch2_name>

git log ^<branch1_name> <branch2_name>

git log <branch2_name> –not <branch1_name>

 

查看某两个branch(branch1、branch2)不重叠的所有commit:

git log …

 

另一种查看log的方式为shortlog,例如查看各个author的commit情况:

git shortlog -s -n

 

格式化显示commit信息:

git log –pretty=format:”% [%]…”

格式化名称请查看:https://www.kernel.org/pub/software/scm/git/docs/git-log.html

 

查看reflog信息:

git log -g

 

添加别名:

git config –global alias. ”

例如:

git config –global alias.unstage ‘reset HEAD –‘

这样,以后unstage某个文件,只要直接输入“git unstage file”就可以了

 

查看当前的所有tag:

git tag

 

checkout至某个tag:

git checkout

checkout后,此时git处于detached head模式,即你可以查看文件但无法提交commit。若想checkout该tag并开始修改,需要为该tag新建branch,即:

git checkout -b

 

git merge可以使用几种策略,这几种策略的对比:

http://stackoverflow.com/questions/366860/when-would-you-use-the-different-git-merge-strategies

 

远端

添加一个远端Repository:

git remote add

例如:

git remote add pb git://github.com/paulboone/ticgit.git

git fetch pb                (使用git fetch将其内容拷贝至本地)

 

同理,删除一个远端Repository:

git remote rm

 

显示远端Repository的url

git remote show  

 

若不需要记录Repository名称,而只要一次性下载某个Repository:

git pull

 

设置远端repository的url:

git remote set-url

 

显示远端repository的所有url:

git remote -v

 

将本地的某个branch提交至远端repository,但本地的branch名字与远端repository中的branch名字不一样:

git push origin :

 

在提交commit至远端repository时,若新的commit并非是远端repository最新commit的祖先,需强制提交:

git push -f

 

当remote repository有新的branch时,使用git fetch origin将该分支下载至本地,你并不能修改该新分支,需进行如下操作才能开始修改:

git checkout -b origin/        (在本地新建该分支)

git merge origin/              (与当前自己的分支merge)

 

删除远端的某个branch:

git push origin :

 

 

 

具体场景

Merge两个分支:

先checkout到要merge的分支上,使用以下命令与远端的分支merge:

git pull

使用以下命令与本地分支merge:

git merge

其中branch_name是被merge的分支名。之后系统会提示哪些文件Auto Conflict失败,需要你手动解决Conflict:

也可以使用git status查看哪些文件需要被修改以解决conflict,通常这些文件被标记Unmerged Paths:

现在进入这些文件,就会发现这些文件被修改了,一部分是你当前分支(要merge)HEAD的代码,一部分是被merge分支HEAD的代码。手动删改直到满意后,使用git add加入到stage area。

最后commit就行了。

 

如果你现在决定不merge了,想要恢复到之前未使用git pull 的状态,请使用:

git reset –merge 

 

若想完全保留当前要merge的分支的代码,完全摒弃被merge分支的与当前分支的不同,就要指明merge的strategy为ours:

git merge -s ours

git pull -s ours origin

参考:http://stackoverflow.com/questions/6006737/git-merge-errors

 

 

Stash用来保存当前工作,而不产生commit:

git stash                                 (保存当前工作)

git stash list                            (用来查看stash保存列表)

git stash apply [stash@{}] –index   (用来回到列表中的某一个stash,num代表该stash记录在stash list中的编号,如果不加,默认回到最近一次的stash。恢复后,该stash记录并不会在stash list中删除)

git stash branch             (如果stash后,继续在同分支上修改代码,在恢复该stash后,可能会产生冲突。使用该命令,可以在恢复该stash时新建一个分支。恢复后该stash记录会被删除。)

 

 

 

删除commit记录中的某个commit:

git rebase -i

在新弹出的记事本中,将以pick起始、想删除的commit那行删除。之后退出保存。弹出的commit为之后的所有commit。

若出现如图中所示的错“could not apply….”错误,多半是因为删除的commit之后的commit产生了冲突。可以考虑用“git rebase –skip”解决。

1

如果记录已经提交到了remote repository上了,需要强制提交:

git push -f

 

 

 

修改commit记录的属性,如作者名、作者Email等。以下是示例代码,按需修改。(以下方法在Windows下的Git Shell中实验失败,但在Ubuntu Terminal下运行正常。):

git filter-branch -f –commit-filter ‘

        if [ “$GIT_AUTHOR_NAME” = “Zhengxing Chen” ];

        then

                GIT_AUTHOR_NAME=”czxttkl”;

                GIT_AUTHOR_EMAIL=”czxttkl@gmail.com”;

                git commit-tree “$@”;

        else

                git commit-tree “$@”;

        fi’ HEAD

若要修改已经提交到远端repository的commit记录,还需要git push -f origin

 

需要回到当前分支之前的某个Commit A,但并不想删除Commit A之后的所有commit,希望在Commit A上另建分支,作为之后所有commit存放的分支:

git branch

git reset –hard HEAD~

若从Commit A继续原Branch的延续,则只需开始工作并commit就可以

若想从当前的commit继续新建分支的延续,则还需git checkout

 

 

 

恢复删除的commit:

通过git reflog查看git引用记录,查看之前被删除commit的SHA-1值。

再开始在被删除的commit上新建recover分支:

git branch

若在reflog中到查不到被删除的commit的SHA-1值,可以通过:

git fsck –full

 

 

合并多个git repository,并且保留(合并)每个repository的历史:

  • 创建parent repository。或者cd到需要作为parent repository的已有repository中。要做为parent repository,repository中至少要有一个commit。
  • 在parent repository下使用以下命令。这一步将需合并的repository作为远端repository添加到parent repository中。

git remote add -f

可以通过git remote -v查看添加后的remote repositor列表。以下图为例,debug就是我添加的子repository。那么我使用的命令即为:

git remote add -f debug ..\..\workspace1\Debug

  • lll将添加的子repository的某个branch合并到parent repository中:

git merge -s ours –no-commit /

其中,repo_name与第二步一致。此步执行后,会提示:“Automatic merge wen well; stopped before committing as requested”

  • 将子repository的该branch作为子文件夹添加到parent repository中:

git read-tree –prefix=/ -u /

  • 最终git commit表示merge完成。

参考地址:http://jasonkarns.com/blog/merge-two-git-repositories-into-one/

 

 

 

 

 

Leave a comment

Your email address will not be published. Required fields are marked *