git branch test: 基于当前commit创建test分支。.git/HEAD 文件中记录了当前分支名字。
git branch -d test:删除本地test分支
git branch -D test: test分支还没有合入当前分支,所以要用-D参数才能删掉。
git push origin --delete test 删除远程test分支
git push origin :test 删除远程test分支
git branch 列出当前分支清单
git branch -a 查看远程分支和本地分支
git branch -v 查看各个分支最后一个提交信息
git branch --merged 查看哪些分支已经合并入当前分支
git fetch origin 同步远程服务器的数据到本地
git checkout -b test origin/test_remote 将远程分支test_remote拉取下来到本地test分支
git checkout test 将远程分支test拉取下来到本地test分支
git pull test从远程分支test 中checkout下来的本地分支test成为跟踪分支,使用git pull或者git push就会操作到对应的远程分支test
分支即是commit的不同引用,在这些分支上,会产生各自的历史。
分支切换即为HEAD引用的一个移动,以及暂存区与工作区的还原。切换分支的时候,会使用分支上最新的提交来还原暂存区和工作区.git checkout test: 切换到test分支,并指向
git checkout test_tag: 切换到test_tag,这时候处于detached HEAD状态。这时可以git checkout -b test_tag来创建test_tag分支,指向test_tag的commit。
fast-forward merge:
git checkout master 切换分支到master
git merge test 将test分支合并到master分支,这时master分支指向的提交就是test分支最新的提交,并不会产生新的提交。
non-fast-forward merge
git checkout master 切换分支到master
git merge test 将test分支合并到master分支,如果有冲突,需要解决冲突后,将改动添加到暂存区,然后git merge --abort,之后再恢复暂存区,再提交后merge。这时就会增加一个提交,相比较于fast-forward merge。
git merge --abort:如果git merge的时候出现冲突,可以执行这个命令取消merge。
注意:如果有没提交的改动,建议不要使用git merge。否则git merge --abort的时候可能不会还原那些改动。
git cherry-pick commit_id 将一个分支的commit_id提交合并到当前分支上,并舍弃另一个分支上的其他提交。
Git merge如何判定冲突,机制如下:
先寻找两个commit的公共祖先,比较同一个文件分别在ours和theirs下对于公共祖先的差异,然后合并这两组差异。如果双方同时修改了一处地方且修改内容不同,就判定为合并冲突,依次输出双方修改的内容。
原理:回到两个分支最近的共同祖先,根据当前分支(也就是要变基的分支)后续历次提交生成一系列补丁文件,然后以基底分支最后一个提交作为新的出发点,应用上这一系列补丁文件,最后生成一个新的合并提交对象。从而修改当前分支的历史,成为基底分支的直接下游; 再使用Fast-forward合并一次即可。(首先用git rebase;再用git merge)
git rebase master test;git checkout master;git merge test 把test分支变基到master分支上
git checkout test; git rebase master;git checkout master;git merge test 把test分支变基到master分支上
git rebase --onto master server client git checkout master;git merge test 取出client分支,找出cient和server分支的共同祖先之后的变化,在master上重演一遍。
规则:不要对远程分支做rebase!
Gerrit ticket rebase:
git checkout ticket: git fetch "ssh://[email protected]:29418/test_repo" refs/changes/88/1729118/19 && git checkout FETCH_HEAD
git pull --rebase origin master 或者 git pull --rebase origin master commit_hash 或者 git pull --rebase origin git_tag
git commit --amend; 如果遇到 remote: error: commit 416eb44: email address [email protected] is not registered in your account, and you lack 'forge author' permission. 问题,则 git commit --amend --author "[email protected]"
git push origin HEAD:refs/for/master 即可产生新的gerrit 单子 或者更新已有的gerrit 单子。
取消git add file的内容:git reset HEAD file
取消修改的内容: git checkout -- file
回退到某个commit:
git reset --hard commit_id 彻底回退到commit_id版本,本地源码也恢复到commit_id版本
git reset --soft commit_id 回退到commit_id版本,修改的文件可以直接再提交
git reset commit_id 默认使用--mixed选项,回退到commit_id版本,修改的文件需要git add后才能提交
git checkout commit_id file_name 取消file_name的commit_id版本提交
HEAD 最近一个提交
HEAD^1 上一次提交
commit_id 每次提交的SHA1值,可以通过git log看到。
git push origin master -f 将当前commit_id的改动强制提交到master分支上。
先取消提交,再修改文件重新提交。
git commit --amend 修改最后一次提交。先git add 新的changes,然后再跑这个命令重新提交。
git stash save -a "stash1": 使用-a参数来保存当前修改为stash1,这时再用git status就看不到之前做的修改了。
还原暂存区的修改:
git stash list:查看所有stash列表
git stash pop --index stash@{0}: 还原stash@{0}的引用,如果加上stash引用,默认还原栈顶的引用。stash@{0}会从stash list中清掉。
git stash apply --index stash@{0}:既还原又保存stash@{0}。
git stash clear 清理所有stash
$ git log -n2
commit 5aade3049c1195e82978e69db864a87e5ac09d5e
Author: aaa
Date:commit aaa
commit f60e3b4c447aabbfcc05b332badf2c7c2861686b
Author: bbb$ git revert 5aade3049c1195e82978e69db864a87e5ac09d5e # 保留5aade3049c1195e82978e69db864a87e5ac09d5e之前的所有提交
$ git push origin master
$ git log -n3
commit 7f71c1429ba3342dd799843aab0bb91d4ebbb5bf
Author: ccc
Date:Revert "commit aaa"
This reverts commit 5aade3049c1195e82978e69db864a87e5ac09d5e.
commit 5aade3049c1195e82978e69db864a87e5ac09d5e
Author: aaa
Date:commit aaa
commit f60e3b4c447aabbfcc05b332badf2c7c2861686b
Author: bbb
命令 | 作用域 | 常用情景 |
---|---|---|
git reset | 提交层面 | 在私有分支上舍弃一些没有提交的更改,撤销提交会重写提交历史, 不能用于公共分支。 |
git reset | 文件层面 | 将文件从缓存区中移除 |
git checkout | 提交层面 | 切换分支或查看旧版本 |
git checkout | 文件层面 | 舍弃工作目录中的更改 |
git revert | 提交层面 | 在公共分支上回滚更改, 在撤销一个提交的同时创建一个新的提交。安全,不会重写历史。 |
git revert | 文件层面 | (然而并没有) |