注释:本文中,中括号内参数表示可选参数,尖括号内参数表示必选参数。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
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”解决。
如果记录已经提交到了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
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/