# Git单独使用的场景

# 删除分支

要删除当前分支首先要切换到其他分支上。

如果分支没有被完全合并,使用git branch -d是不能删除的,此时需要使用:

git branch -D branchName

# 修改注释

# 修改最近一次commit的注释

git commit --amend

# 修改以前commit的注释

git rebase -i targetCommitFatherHash
git rebase -i 2a5f60e

根据下面的提示信息:

# r, reword <commit> = use commit, but edit the commit message

修改将要修改的commit改变:

r e4abe2e change file hello.txt
pick 4b15340 initfile
1
2

编辑完保存,然后会弹出要修改commit的注释信息,修改完保存即可。操作成功后会提示:

[detached HEAD 07f404d] change file hello.txt 201911:
 Date: Sun Oct 20 15:56:29 2019 +0800
 1 file changed, 3 insertions(+), 1 deletion(-)
Successfully rebased and updated refs/heads/temp.
1
2
3
4

这条git命令意为变基,这是什么意思呢?再执行下变基命令,看到如下结果:

pick 07f404d change a file named hello.txt
pick 56328e5 initfile
1
2

发现从命令指定commit的2a5f60e后面所有commit都变了,根据成功操作后的提示[detached HEAD 07f404d],可以猜想,git应该是切换到我们指定的commit上执行完操作再合并回来。

注意,这个会修改执行操作的commit,所以这个只是单人在自己分支场景下的操作,分支还没有贡献到集成分支上,不能在多人场景中使用。

# 合并Commit

# 合并连续的Commit

进入变基的交互模式:

git rebase -i targetCommitFatherHash

在该模式下,要被合并到的commit保持pick不变,要合并的commit前面改成s,保存后会提示要写合并commit后的注释,写完保存即可完成合并。

# 合并不连续的Commit

第一步进入变基交互模式,第二步将要合并的不连续的commit归并到第一个被合并的commit下面,并将操作改为s,保存退出。注意如果要将第一个commit设置为被合并的commit,但是在变基交互模式下不显示时,需要手动写pick firstCommit。此时提示如下:

interactive rebase in progress; onto 2a5f60e
Last command done (1 command done):
   pick 2a5f60e
Next commands to do (2 remaining commands):
   squash ab2c712 20191110 test last3
   pick 9aaec62 this is a test merge
You are currently rebasing branch 'temp' on '2a5f60e'.

nothing to commit, working tree clean
The previous cherry-pick is now empty, possibly due to conflict resolution.
If you wish to commit it anyway, use:

    git commit --allow-empty

Otherwise, please use 'git reset'
Could not apply 2a5f60e...

如果使用git status显示当前的状态就是:

interactive rebase in progress; onto 2a5f60e
Last command done (1 command done):
   pick 2a5f60e
Next commands to do (2 remaining commands):
   squash ab2c712 20191110 test last3
   pick 9aaec62 this is a test merge
  (use "git rebase --edit-todo" to view and edit)
You are currently rebasing branch 'temp' on '2a5f60e'.
  (all conflicts fixed: run "git rebase --continue")

nothing to commit, working tree clean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

此时需要运行git rebase --continue,这样便完成合并。注意此时使用gitk能看到有两棵树。

# 比较差异

比较暂存区和HEAD之间的差异:

git diff --cached

比较工作区和暂存区之间的差异:

git diff

比较不同Commit的指定文件的差异:

git diff branchName1 branchName2 filename
git diff commitHash1 commitHash2 filename

# 恢复

reset

当工作区的方案比暂存区的方案好时,我们想清空暂存区,即把暂存区恢复成和HEAD一样:

git reset HEAD

当我们只想把部分暂存区恢复成和HEAD一样时:

git reset HEAD filename

当暂存区的方案比工作区的方案好时,我们希望将工作区恢复成和暂存区一样的:

git checkout filename

注意,如果想要变更工作区的内容,使用checkout,如果想要变更暂存区的内容,使用reset。

消除最近几次commit,也就是退回到某个commit,并将工作区和暂存区也恢复到那个commit:

git reset --hard targetHeadHashCode

比如想抛弃工作区和暂存区的所有内容,恢复到最近的commit:

git reset --hard head

# 删除文件

同时从工作区和Git控制中删除某个文件:

git rm filename

只从Git控制中删除某个文件:

git rm --cached filename

只从硬盘上删除某个文件,不从Git控制中删除该文件:

rm filename

# Git仓库备份

# 传输协议

常用协议 语法格式 类型
本地协议1 /path/to/repo.git 哑协议
本地协议2 file:///path/to/repo.git 智能协议
http/https协议 http://git-server.com:port/path/to/repo.git 智能协议
ssh协议 user@git-server.com:path/to/repo.git 智能协议

智能协议和哑协议的区别:

  1. 哑协议传输进度不可见,智能协议传输可见。
  2. 智能协议比哑协议传输速度快。

# Git备份

# 哑协议备份

git clone --bare C:\Users\user\Desktop\gitLearn.git test1.git

# 智能协议备份

git clone --bare file:///C:\Users\user\Desktop\gitLearn.git test2.git

# 向源仓库push

在上面的test1或test2仓库添加远程仓库分支名字:

git remote add local1 file:///C:\Users\user\Desktop\gitLearn.git

接下来将变更向该远程仓库推送即可:

git push local1

# 忽略文件

在git管理的项目中,有一些文件是构建程序的中间文件,或者是不想被管理的文件,那么如何让这些文件被git忽视呢?在项目目录下建立文件.gitignore,然后在该文件中写入要被忽略的文件名即可,可以使用通配符。下面是忽略规则:

# 忽略target文件和target目录:
target
# 只忽略target目录,不忽略target文件
target/
# 只忽略target文件,不忽略target目录
target
!target/
# 只忽略当前目录下的target文件和目录,子目录的target不在忽略范围内
/target
# 忽略*.o和*.a文件
*.[oa]
# 忽略*.b和*.B文件,mg.b除外
*.[bB]
!mg.b
1
2
3
4
5
6
7
8
9
10
11
12
13
14

下面是它的通配符规则:

#:注释行
?:任意一个字符
*:代表任意数目字符
{!ab}:必须不是ab类型
{ab,bb,cx}:代表ab,bb,cx中任一类型即可
[abc]:代表a,b,c中任一字符即可
[^abc]:代表必须不是a,b,c中任一字符
1
2
3
4
5
6
7

# 忽略文件失效的情况

  1. 被忽略的文件已经被加入到Git管理中,此时需要将暂存区中的缓存清理下,可以使用git rm -r --cached fileName将指定文件从git缓存中清除,或者直接将当前目录的缓存都清除git rm -r --cached .。
  2. .gitignore自身编码问题,可以转换成UTF-8再尝试下。

# 其他场景

# 临时修改bug

现在有一种场景是你正在为一个新特性工作,暂存区有几个文件,工作区有几个文件,此时突然有测试报告称有重大bug,你需要切回目标分支,修改bug再返回来继续工作。

首先保存当前的工作区和暂存区:

git stash

切换到其他地方进行修复,修复完成后,将之前的工作区和暂存区取出:

git stash apply
git stash apply stashNum

上面的命令是将内容从git stash处恢复到当前的工作区和暂存区,但是并不清除这个stash的内容。 可以使用下面命令查看stash区域中的东西:

git stash list

如果想要恢复到当前的同时清除掉stash中的内容:

git stash pop
git stash pop stashNum

注意stash区域就是一个堆栈,越先进入stash的序号越大,默认序号0为堆栈首部。

注意,如果一个文件没有被放到暂存区只存在于工作区,那么stash后再取出来它也只存在于工作区。如果一个文件被放到暂存区中,在工作区中又修改了,那么它stash后再取出来后,它之前在工作区中的修改也会被放到暂存区。