1. diff 与 patch
两个文件:source.txt target.txt
hello world
4
1
diff 来比较两个文件的差异:
2、git reset :
重置文件:git reset [-q] [<commit>] -- paths
不影响工作区、暂存区、版本库。
用commit中的文件覆盖相当于将文件从暂存区中拿出来,恢复到没有add
3、 git checkout
- 切换分支
-
git checkout -- file:
用暂存区的文件覆盖工作区文件 -
git checkout commit file:
用commit中的文件覆盖 暂存区和工作区
4、忽略文件
-
.gitignore
对未跟踪的文件有效,- 范围:所在目录及子目录起作用。共享式,会随着项目而生效
如果文件被忽略,可以使用
git add -f file
来添加文件,添加进去的文件将不受.gitignore
影响 -
.git/info/exclude
项目独享式 -
git config —global core.excludesfile ~/.gitignore:
全局独享式,对所有的git项目都起作用
5、文件归档
git archive -o targe.zip HEAD
git archive -o partial.tar HEAD src doc
-
git. archive —format=tar —prefix=1.0/ v1.0 | gzip > foo-1.0.tar.gz;
使用 tag,最后会产生1.0目录,下面是
tag v1.0
的所有文件
6、清除未跟踪文件
git clean -n -fd
:
-
-n
显示即将删除的文件; - 这里的删除指的是
git
不追踪 这些文件,并不删除物理文件。因为有时会产生很多临时文件,随时改动.gitignore
太麻烦,这时使用git clean -n -fd
可以使得git
不追踪这些没有添加到git
库中的文件。
7、保存恢复工作进度
-
git stash
: 默认会重置工作区和暂存区-
--keep-index
:不会重置暂存区 -
"message"
: 保存进度时留下提醒信息
-
8、git cherry-pick
3 步走:挑选提交 --- 切换到当前分支 --- 覆盖工作区和暂存区
git cherry-pick commit
git checkout currentBranch
git reset --hard HEAD@{1}
挑选指定提交放入到当前的HEAD;
假设有A B C D E F
这6个提交记录, 现要挑选E F
并放到C
上,即删除D
,如下:
-
git checkout
到指定提交:git checkout D^
-
git cherry-pick E
:将提交点 E 放入当前HEAD, HEAD前进一步指向E。 -
git cherry-pick F
:将提交点 F 放入当前HEAD, HEAD前进一步指向TagF。 -
git checkout dev;
git reset --hard HEAD@{1}
:git checkout dev
也会产生一个commit,所以应该使用HEAD@{1}
来覆盖当前的版本库。 - 结束,其中上一步是至关重要的。
将
C 和 D
的提交说明合并为一个提交说明,这里合并为C
的提交说明。
因为只是合并提交说明,所以,
应该将版本库git reset --soft
到B
;
工作区和暂存区git checkout D
, 然后commit
产生一条新的记录,
并将E F
放到当前HEAD
-
git checkout D
:工作区和暂存区切换到D
-
git reset --soft HEAD^^
: 版本库切换到B
-
git commit -C C
:使用C
的提交说明,进行提交 -
git cherry-pick E, git cherry-pick F
:将 E 和 F 重放到当前的HEAD -
git checkout dev, git reset --hard HEAD@{1}
: 覆盖工作区
9、git rebase
git rebase --onto base since_commit till_commit
3 步走:切到新的
HEAD
(一个 commit)--- 拣选区间 --- 更新工作区和暂存区
变基操作:
git cherry-pick
一个一个挑选,git rebase
挑选(since_commit, till_commit]
区间段的提交
删除提交D:
-
git checkout D^
: -
git rebase --onto= HEAD E^ dev
: 相当于git rebase --onto= HEAD E^ F git checkout dev git reset --hard HEAD@{1}
合并提交C 和 D
:
git checkout D
-
git reset --soft HEAD^^
:版本库回退到B
(C
的前面提交) -
git commit -C C
:使用提交 C 的提交记录作为新的提交记录 -
git rebase --onto=HEAD E^ dev
:将[E, ]
区间的提交放入 HEAD上,并修改工作区和暂存区。
10、git rebase -i commit^
以
commit
作为HEAD
进行交互式git rebase
,通过编辑 编辑操作文件来完成相应的工作。
11、删除提交历史说明
这里删除的是提交说明,而不是提交!
2 步:构造一个新的根提交 --- 将想要保存的提交历史说明变基到该新的提交
只保留 B 之后的提交说明,如下:
-
构造一个新的根提交
-
git commit-tree B^{tree} -m commit-log
: 得到一个commit-id 0a47615cc90f6a5b82
。 -
将 B 的将提交记录中 parent-commit 删除
,将剩下的信息作为commit 对象
写入对象库,构造成为一个根提交。# 1. 提交 B 的 log git cat-file commit B^0 : tree e0e82db036311d293e97d4cab06194fc2f999d14 parent e5724199303f41c6fbdbaa6e43896c98f041367c author jack <yudianer1991@hotmail.com> 1533474089 +0800 committer jack <yudianer1991@hotmail.com> 1533474089 +0800 B # 2. 保存去除 parent 之后的信息, 保存到 tmpfile git cat-file commit B^0 | sed -e "/^parent/d" > tmpfile tmpfile 内容: tree e0e82db036311d293e97d4cab06194fc2f999d14 author jack <yudianer1991@hotmail.com> 1533474089 +0800 committer jack <yudianer1991@hotmail.com> 1533474089 +0800 B # 3. 将 tmpfile 内容写入对象库,形成新的根提交 git hash-object -t commit -w tmpfile -t: 指定产生的对象的类别 -w: 指定写入对象库的文件 产生 commit-id:bee2b046d9d36a18d1c3e95077a92014b4b5bf89
-
将
B^ dev
的提交记录变基到新的根提交:
git rebase --onto=bee2b046d9d36a1 B^ dev
-
最终提交记录:
5172477f5b4d4c56828461ded63447fee869b4dd (HEAD -> dev) g 2113fa495b5c084b286e18ada708826a9e4d3a85 F 83a66109b5a4922a770a914e608d65d003646749 E a2cafa33143a369be71faa02ddb329266541f2fc D a68285d9a1832e508429a0b9f39fa638d9dbf667 C bee2b046d9d36a18d1c3e95077a92014b4b5bf89 B
12、 git revert
git revert commit-id :
撤销 commit-id 对应的提交,但是不会删除commit-id
的提交记录,这是需要手动删除的.
13、 git push
快进式操作: 在
git push
提交的时候,如果当前的commit是远程版本库当前分支现有的基础上,即远程版本库的最新commit
是本地当前分支最新提交的祖先提交,那么直接提交。 一般情况下只允许快进式提交
。
git push -f:
如果提交不通过快进式操作
检验,则会出现非快进式
错误,那么可以使用git push -f
来强制推送更新远程版本库。
-
git rev-list HEAD --max-count=5 :
查看本地 HEAD 上最新的 5 个提交。 -
git ls-remote origin :
查看远程各个分支的的最新commit-id
通过git rev-list HEAD --max-count=5
和 git ls-remote origin
可以对比是否会产生非快进式操作问题。
14、 git log
-
git log -3 --stat --online
: 显示前3个 log 信息,并呈现提交的变更。
git log -3 --stat --oneline --pretty=full --graph :
* commit e40d1be (HEAD -> dev, origin/dev)
| Author: jack <yudianer1991@hotmail.com>
| Commit: jack <yudianer1991@hotmail.com>
|
| g
|
| new.file | 2 ++
| rebase | 1 +
| 2 files changed, 3 insertions(+)
|
* commit 61ce462 (tag: F)
| Author: jack <yudianer1991@hotmail.com>
| Commit: jack <yudianer1991@hotmail.com>
|
| F
|
| rebase | 1 +
| 1 file changed, 1 insertion(+)
|
* commit cce0039 (tag: E)
| Author: jack <yudianer1991@hotmail.com>
| Commit: jack <yudianer1991@hotmail.com>
|
| E
|
| rebase | 1 +
| 1 file changed, 1 insertion(+)
14、 git tag
tag 创建之后默认不会推送到远程版本库,必须显示地
git push origin tagname
提交tagname
, 或者git push origin refs/tags/*
来推送所有的tag。
git pull
时默认会拉取所有的 tag,但是在tag有更新时,不会拉取更新后的tag内容。
git pull refs/tags/mytag:refs/tags/mytag :
将会强制用远程的mytag
来更新本地的mytag
1、创建 tag
git tag tagname [<commit>]
-
git tag -m msg -s tagname [<commit>]
:-
-m:
添加 tag 说明 -
-s:
添加签名
-
2、查看 tag
-
git tag -l my*
: 列出 能够匹配my*
的tag
3、删除 tag
-
git tag -d tagname:
删除本地的 tagname -
git push origin :tagname:
删除远程的 tagname
15、分支
1、创建分支
-
git branch <branch-name> <commit-id>:
从commit-id
出建立分支,默认是从HEAD。 -
git push -u origin <new-branch-name>:
将本地<new-branch-name>
分支推向远程,-u
自动跟踪远程的同名分支。
git branch --set-upstream-to=origin/dev:
当前分支自动跟踪远程的dev
分支。
2、删除分支
-
git branch [-d|-D] branch-name
:删除本地分支
-d :
如果branch-name
已经合并到其他分支,则删除。
-D :
直接强制删除。 -
git push origin :branch-name
:删除远程branch-name
分支。 -
git branch [-m|-M] branch-old-name branch-new-name
:更换branch名称
-m
: 如果已经存在branch-new-name ,更名失败。
-M
:强制更名。
3、查看分支
-
git branch
:查看本地分支。 -
git branch -r | git ls-remote :
查看远程分支。
4、跟踪分支
-
git branch -b local-branch origin/branch
:基于远程branch
分支创建本地分支,并追踪。 -
git branch --set-upstream-to=origin/dev
:追踪origin/dev
16、远程版本库
-
git remote add origin git-url
:添加版本库 -
git remote set-url origin new-git-url
:更新git-url
,pull 和 push 的url 可以单独设置。 -
git remote rename origin new-name
:更新 origin 为 new-name 名称。 -
git remote update
:同时更新所有的版本库。 -
git remote rm origin:
删除对 origin 对应的版本的跟踪。如果后面通过git add
的方式添加了origin, 那么还需要对所有的分支设置跟踪远程分支。