1. 合并merge:
通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward模式(git merge --no-ff -m "merge with no-ff" dev),Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
可以看到,不使用Fast forward模式,merge后就像这样:
merge 冲突
当 Git 不不知道怎么合并某两处冲突的修改时,会中断⾃自动合并,并对冲突⽂文件进⾏行行标记。解决方法:
1. 把文件⼿动修改好
2. 把修改的内容使用add 来添加进暂存区
3. ⽤git merge --continue 来继续⾃动合并流程
2. 变基rebase
把当前 commit(以及它之前的 commits)应⽤到指定的需要 rebase 的 commit 上。
Git 中的每⼀个 commit 都是不会改变的,所以 rebase 之后的每个 commit 都是新产⽣的,⽽不是对原先的 commit 进行「修改」
rebase 冲突
rebase 的冲突解决方法和 merge 冲突⼀样,只是把 git merge --continue 改成 git rebase --continue 就⾏了
提交过的东西写错了
1. 最新的一条内容需要修改: git commit --amend(修改最后一次提交的内容)
「修改」只是概念⾏为,实质上会产生⼀个新的 commit(修改后的commit id 变了)
步骤:
修改需要的文件
添加修改文件到暂存区 add
执行 git commit --amend 命令行工具会提示修改提交信息
对应AndroidStudio操作 :提交界面勾选 Amend commit 即可
2. 旧的内容需要修改:
git rebase -i 指定的commit 交互式 rebase
交互式 rebase 不止可以修改 commit,还能增加和删除
例: 假如需要删除某个commit,使用git rebase -i <需要删除的commit的父commit>,再进行交互式rebase,如果出现冲突,按照rebase 冲突解决方式就好
3. 已经 push 到 master 的内容需要删除:
不能⽤ rebase,因为 master 上的东西是不能强行修改的
可以⽤ git revert 指定commit 来撤销。它的原理是创建⼀个新的 commit,内容是指定 commit 的「相反内容」
3. 重置reset
把当前 branch 指向指定的 commit。
git reset 指定commit
移动到指定 commit,并把当前位置和指定位置的文件差异加入 working tree
注意: 如果要切换回去,用 git reflog 查看之前操作记录
对应AndroidStudio操作 : 某个commit上右键选择 Undo Commit (只支持操作最近一次提交)
git reset --hard 指定commit
移动到指定 commit,并重置 working tree(当前位置和指定位置的文件差异不会加入working tree,并且之前工作空间内容没了)
对应AndroidStudio操作 : 某个commit上右键选择 Reset Current Branch to Here..
reset 和 checkout 的区别
它们都是移动 HEAD,但 chekcout 移动的时候是自⼰移动,不带着 branch 一起;
⽽reset 会带着 branch 一起移动。
4. 储藏Stash:
储藏工作:
使用 git stash save "message"(暂存区和工作区的文件会被保存) 保存工作区的修改。
默认情况下,git stash 只会储藏已经在索引中的文件(未跟踪的文件不会储藏)。
使用 git stash apply stash@{2} 应用储藏,文件的改动被重新应用了,但是之前暂存的文件却没有重新暂存。 想要那样的话,必须使用 --index 选项来运行 git stash apply 命令,来尝试重新应用暂存的修改。 如果已经那样做了,那么你将回到原来的位置(比如原来在暂存区的文件还会在暂存区,新创建的文件没这个现象):
对应AndroidStudio 中的操作为: apply时,勾选Reinstate index
$ git stash apply --index
# On branch master
# Changes to be committed:
# (use "git reset HEAD
#
# modified: index.html
#
# Changed but not updated:
# (use "git add
#
# modified: lib/simplegit.rb
#
应用选项只会尝试应用暂存的工作——在堆栈上还有它。 可以运行 git stash drop 加上将要移除的储藏的名字来移除它:
$ git stash list
stash@{0}: WIP on master: 049d078 added the index file
stash@{1}: WIP on master: c264051 Revert "added file_size"
stash@{2}: WIP on master: 21d80a5 added number to log
$ git stash drop stash@{0}
Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43)
也可以运行 git stash pop 来应用储藏然后立即从栈上扔掉它。
创造性的储藏:
有几个储藏的变种可能也很有用。 第一个非常流行的选项是 stash save 命令的 --keep-index 选项。 它告诉 Git 不要储藏任何你通过 git add 命令已暂存的东西。(在保存进度后不会将暂存区重置,暂存区的修改还是保持原样,默认会将暂存区和工作区强制重置(也就是所有修改都会还原),即命令:–no-keep-index的效果)
当你做了几个改动并只想提交其中的一部分,过一会儿再回来处理剩余改动时,这个功能会很有用。
$ git status -s
M index.html
M lib/simplegit.rb
$ git stash --keep-index
Saved working directory and index state WIP on master: 1b65b17 added the index file
HEAD is now at 1b65b17 added the index file
$ git status -s
M index.html
另一个经常使用储藏来做的事情是像储藏跟踪文件一样储藏未跟踪文件。 默认情况下,git stash 只会储藏已经在索引中的文件。 如果指定 --include-untracked 或 -u 标记,Git 也会储藏任何创建的未跟踪文件(储藏未跟踪的文件AS通过view无法查看diff)。
$ git status -s
M index.html
M lib/simplegit.rb
?? new-file.txt
$ git stash -u
Saved working directory and index state WIP on master: 1b65b17 added the index file
HEAD is now at 1b65b17 added the index file
$ git status -s
$
如果想存储指定的块,可以使用git stash --patch(或git stash -p) – 你将进入交互模式,在那里你将看到每个改变的Hunk。使用 n 跳过你不想要保存的文件,y 保存需要的文件。
最终,如果指定了 --patch 标记,Git 不会储藏所有修改过的任何东西,但是会交互式地提示哪些改动想要储藏、哪些改动需要保存在工作目录中。
$ git stash --patch
diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index 66d332e..8bb5674 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -16,6 +16,10 @@ class SimpleGit
return `#{git_cmd} 2>&1`.chomp
end
end
+
+ def show(treeish = 'master')
+ command("git show #{treeish}")
+ end
end
test
Stash this hunk [y,n,q,a,d,/,e,?]? y
Saved working directory and index state WIP on master: 1b65b17 added the index file
3. git stash --keep-index说明:
git stash --keep-index 它告诉 Git 不要储藏任何你通过 git add 命令已暂存的东西。
5. 版本回退:
场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file。
场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,
第一步用命令git reset HEAD
场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退一节,不过前提是没有推送到远程库。
6. add -i 交互式 add ⽤用法:
git add -i
常⽤选项:
p (patch)
选取块时的常用选项:
y:选用当前块
n:不用当前块
s:把当前块做自动切分后再重新询问
e:⼿动选取修改内容
AndroidStudio操作为:在提交diff界面,代码块的勾选☑️框
7. 标记tag
另一种引⽤用类型。
和 branch 区别之⼀:不能改变
和 branch 区别之⼆:不能被 HEAD 指向
用处:设置持久标记,例如版本号
origin/master, origin/feature, origin/HEAD 和 tag 有相似之处:也不能从本地改变位置,也不能被 HEAD 指向
8. reflog
⽤法:
git reflog
用途:
查看指定的引⽤(HEAD 或 branch)的移动历史,从而找到之前的某个特定 commit
9. cherry-pick
⽤法:
git cherry-pick commit1 commit2
用途:
应用指定的某个或某些 commit 到 HEAD 处
常用AndroidStudio git 指令:
reword 更改commit 提交说明信息