Git提高

add了不需要的文件

在开发过程中, 有时候使用add ., 但是忘记配置.gitignore, 导致很多不必要的文件被添加到暂存区

这个时候我们就可以使用git rm命令删除文件

1
2
3
4
5
# 连同工作区和暂存区一起删除
git rm fileName

# 仅删除暂存区的文件
git rm --cached fileName

演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
root@MagicBookPro:~/git-learn# git add .

# 发现所有文件不小心被添加到暂存区
root@MagicBookPro:~/git-learn# git status
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: READEME.md
new file: project.config

# 从暂存区里面移除
root@MagicBookPro:~/git-learn# git rm --cached project.config
rm 'project.config'

# 查看status, 发现 project.config 从暂存区中移除, 未被 tracked
root@MagicBookPro:~/git-learn# git status
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: READEME.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
project.config

提交了错误的commit信息

在开发过程中, 很多时候不小心写错了commit信息, 等commit之后才发现, 我们提交的时候可以使用--amend 参数来重新覆盖上一次的提交

如果代码写错了, 也可以使用--amend 覆盖上一次的提交

演示

本来commit表示没有bug, 不小心写成了有bug, 使用--amend覆盖上一次提交

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 发现错误的commit信息
root@MagicBookPro:~/git-learn# git log
commit 9989907978f4429784ddab44cd6609052e714397 (HEAD -> master)
Author: root <root@MagicBookPro.localdomain>
Date: Wed Jul 13 12:01:47 2022 +0800

There is a bug
# amend覆盖上次提交
root@MagicBookPro:~/git-learn# git commit --amend -m "There is no bug"

# 一切正常了
root@MagicBookPro:~/git-learn# git log
commit fa317bef970371b805543de2c3b874a8000dc583 (HEAD -> master)
Author: root <root@MagicBookPro.localdomain>
Date: Wed Jul 13 12:01:47 2022 +0800

There is no bug

修改了工作区, 想从暂存区中恢复

从暂存区里面恢复可以使用git restore 命令

1
2
3
4
# 将工作区的文件从暂存区恢复 
git resotre fileName
# 将暂存区的文件从分支里恢复
git restore --staged fileName

演示

成功将工作区的文件从暂存区恢复

1
2
3
4
5
6
7
8
9
root@MagicBookPro:~/git-learn# cat READEME.md
This is first commit
root@MagicBookPro:~/git-learn# git add .
root@MagicBookPro:~/git-learn# vim READEME.md
root@MagicBookPro:~/git-learn# cat READEME.md
test restore
root@MagicBookPro:~/git-learn# git restore READEME.md
root@MagicBookPro:~/git-learn# cat READEME.md
This is first commit

修改了工作区, 想从分支中恢复

修改了工作区, 想从分支中恢复可以使用git reset命令, 尽量少使用

1
2
3
# reset的原理就是将HEAD指针向后移动至目标commit上。
git reset --hard # 默认HEAD
git reset --hard commitId

优点:操作便捷,可保持干净的提交历史

缺点:

  1. 危险命令,容易丢失东西
  2. 如果有其他分支已经基于reset前的版本进行迭代开发,那两者再次merge 或者rebase的时候被revert的commit还是会出现,

演示

1
2
3
4
5
6
7
root@MagicBookPro:~/git-learn# vim READEME.md
root@MagicBookPro:~/git-learn# cat READEME.md
asdfsdfsjfklsafjsklfThis is first commit
root@MagicBookPro:~/git-learn# git reset --hard
HEAD is now at fa317be There is a bug
root@MagicBookPro:~/git-learn# cat READEME.md
This is first commit

当前代码还未commit, 需要切换到另一个分支修复bug

可以使用 stash, 将工作区暂时保存起来, 等另一个分支完成后再切换回来继续code

1
2
3
4
5
6
7
8
# 贮藏当前代码
git stash
# 查看贮藏起来的分支
git stash list
# 删除stash
git stash pop
# 恢复到指定stash
git stash apply stash@{0}

演示

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
31
32
33
34
# 查看所有分支
root@MagicBookPro:~/git-learn# git branch
bugfix
* master

# 切换不成功, 有没有提交的 changes
# 只有分支指向同一个commit才能切换, 这里为了演示在mater分支上提交了一次
root@MagicBookPro:~/git-learn# git switch bugfix
error: Your local changes to the following files would be overwritten by checkout:
READEME.md
Please commit your changes or stash them before you switch branches.
Aborting

# 贮藏当前代码
root@MagicBookPro:~/git-learn# git stash
Saved working directory and index state WIP on master: ee009aa 123

# 成功切换
root@MagicBookPro:~/git-learn# git switch bugfix
Switched to branch 'bugfix'

# 切换为原分支
root@MagicBookPro:~/git-learn# git switch master
Switched to branch 'master'

# 恢复代码
root@MagicBookPro:~/git-learn# git stash apply
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: READEME.md

no changes added to commit (use "git add" and/or "git commit -a")

这次的commit有很大问题, 需要撤销commit

这个时候可以使用git revert commitId命令, 这个命令commit一个新的提交, 这个新的提交就是当前提交的上一个提交, 这个使用了一个反向操作.

1
2
3
4
5
6
7
8
9
10
11
# 使用命令前
commit 1
commit 0

# revert, 如果revert非最新分支, 可能要进行解决冲突
git revert commit 1

# 使用命令后, 产生一个新的提交, 新的提交就是原 commit 0
commit 2 Revert to commit 0
commit 1
commit 0

演示

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 进行一个错误的提交
root@MagicBookPro:~/git-learn# git commit -m "wrong commit"
[bugfix 5acae94] wrong commit

# log
root@MagicBookPro:~/git-learn# git log
commit 5acae9443d4a0390545f704df972a6f4401ed34a (HEAD -> bugfix)
Author: root <root@MagicBookPro.localdomain>
Date: Wed Jul 13 12:49:01 2022 +0800

wrong commit

commit fa317bef970371b805543de2c3b874a8000dc583
Author: root <root@MagicBookPro.localdomain>
Date: Wed Jul 13 12:01:47 2022 +0800

There is a bug

# revert
root@MagicBookPro:~/git-learn# git revert 5acae9443d4a0390545f704df972a6f4401ed34a

# 有一个新的提交
root@MagicBookPro:~/git-learn# git log
commit cbf64d20186c9c94989dee6c8a9484500cc71896 (HEAD -> bugfix)
Author: root <root@MagicBookPro.localdomain>
Date: Wed Jul 13 12:53:26 2022 +0800

Revert "wrong commit"

This reverts commit 5acae9443d4a0390545f704df972a6f4401ed34a.

commit 5acae9443d4a0390545f704df972a6f4401ed34a
Author: root <root@MagicBookPro.localdomain>
Date: Wed Jul 13 12:49:01 2022 +0800

wrong commit

commit fa317bef970371b805543de2c3b874a8000dc583
Author: root <root@MagicBookPro.localdomain>
Date: Wed Jul 13 12:01:47 2022 +0800

There is a bug

# 就是 wrong commit 的上一个提交内容
root@MagicBookPro:~/git-learn# cat READEME.md
This is first commit

将本地仓库关联并push到多个远程仓库

演示

1
2
3
4
5
6
7
8
9
10
11
# 添加远程 origin
root@MagicBookPro:~/git-learn# git remote add origin git@gitee.com:clouderhem/one.git
# 添加远程 origin2
root@MagicBookPro:~/git-learn# git remote add origin2 git@gitee.com:clouderhem/two.git

# 推送到origin 的 master 分支
root@MagicBookPro:~/git-learn# git push origin master

# 推送到origin2 的 master 分支
root@MagicBookPro:~/git-learn# git push origin2 master

推送了n个错误的commit到主分支

注意: 提交容易丢失, 谨慎使用

操作

1
2
3
4
5
6
7
8
9
# 切换到正确的开始的提交
git checkout commitId
# 删除主分支
git branch -d master
# 创建主分支, 此时master指向本提交
git branch master
# 强制推送或者删除远程master分支后再推送到master
# commitId后面的提交将丢失
git push origin master -f

Merge 和 Rebase

将dev分支修改合并到main分支上

  1. merge

  2. rebase

    将c2, c3 复制到dev上产生新的提交,

其他命令

clone

1
2
# The result contains only commit chains with a length of at most n
git clone --depth n

alias

给命令起别名

示例

1
2
3
4
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status

config

1
2
3
4
5
6
# 编辑config, 仅本仓库
git config -e
# 全局配置
git config --global -e
# 查看 config
git config --list

blame

显示每一个文件中每一行代码的作者

1
git blame fileName

cherry-pick

1
2
# 从不同的分支中选择单个提交和将它和当前分支的合并
git cherry-pick commitId

附加

  1. Git分支模拟
  2. 廖雪峰的git教程

声明

如有错误请联系作者更正