git小技巧

基础概念

一个文件从改动到提交到 Git 仓库,需要经历三个状态:

  • 工作区:工作区指的是我们本地工作的目录,比如我们可以在刚才创建的 hackers 目录下新增一个 readme 文件,readme 文件这时只是本地文件系统上的修改,还未存储到 Git。
  • 暂存(索引)区:暂存实际上是将我们本地文件系统的改动转化为 Git 的对象存储的过程。
  • 仓库:git commit 后将提交对象存储到 Git 仓库。

git stash

应用场景

  • 当正在某个分支A上开发某个项目,这时项目中出现一个bug需要紧急修复,但是正在开发的内容只是完成一半还不想提交,这时git stash命令可以将修改的内容保存至堆栈区,等修复完成后,再次切回到dev分支,从堆栈中恢复刚刚保存的内容。
  • 想比较修改文件部分的性能进些比较,不想再拷贝一份源码,可以利用git stash进些多个版本的切换而不必提交。
  • 本应该在dev分支开发的内容,却在master上进行了开发,需要重新切回到dev分支上进行开发,可以用git stash将内容保存至堆栈中,切回到dev分支后,再次恢复内容即可。

命令

将所有未提交的修改(工作区和暂存区)保存至堆栈中,可用于后续恢复当前工作目录。

试验项目目录:

1
2
$ ls
LICENSE test

1. 把当前修改添加到临时堆栈中:

1
2
3
$ git stash
Saved working directory and index state WIP on master: 454104b Initial commit
HEAD is now at 454104b Initial commit

注:如何该文件是新添加的,需要git add先添加到暂存区。

2. 把当前修改添加到临时堆栈中,并可以通过save命名:

1
2
3
$ git stash save "fix test field"
Saved working directory and index state On master: fix test field
HEAD is now at 454104b Initial commit

3. 查看当前stash中的内容:

1
2
$ git stash list
stash@{0}: On master: fix test field

4. 将当前stash中的内容弹出(弹出内容会删除),并应用到当前分支对应的工作目录上:

1
$ git stash pop

pop采用的是先进后出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ git stash list
stash@{0}: On master: add test2
stash@{1}: On master: add test1
stash@{2}: On master: add test

$ git stash pop
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: LICENSE
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# test
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (ea8db073e65ab6d9cad25609838a7f2e49c011a9)

$ git stash list
stash@{0}: On master: add test1
stash@{1}: On master: add test

5. 堆栈中的内容应用到当前目录,而不删除:

使用apply

1
2
3
4
5
6
7
8
9
10
11
12
13
$ git stash apply stash@{1}
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: LICENSE
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# test
no changes added to commit (use "git add" and/or "git commit -a")

6. 清除堆栈中的所有内容:

1
$ git stash clear

7. 从堆栈中移除某个指定的stash:

1
2
3
4
5
6
7
8
9
10
11
$ git stash list
stash@{0}: WIP on master: 454104b Initial commit
stash@{1}: On master: add test1
stash@{2}: On master: add test

$ git stash drop stash@{1}
Dropped stash@{1} (e998224cb579b6a8ae44795abf40b7658a90d487)

$ git stash list
stash@{0}: WIP on master: 454104b Initial commit
stash@{1}: On master: add test
  1. 查看堆栈中最新保存的stash和当前目录的差异:
    1
    2
    3
    $ git stash show
    LICENSE | 2 +-
    1 file changed, 1 insertion(+), 1 deletion(-)

git commit –amend

应用场景

在commit之后发现发现漏掉了几个文件没有添加,或者提交信息写错,可以用--amend修改并重新提交。

命令

比如:

1
2
3
$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend

注:当你在修补最后的提交时,并不是通过用改进后的提交 原位替换 掉旧有提交的方式来修复的, 理解这一点非常重要。从效果上来说,就像是旧有的提交从未存在过一样,它并不会出现在仓库的历史中。在 Git 中任何 commit 的东西几乎总是可以恢复的,那些被删除的分支中的提交或使用 –amend 选项覆盖的提交也可以恢复

场景:

1
2
3
4
5
6
7
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: test
#

如果添加错了一个修改到暂存区,我们可以通过git reset HEAD的方式重置:

1
2
3
4
5
6
7
8
$ git reset HEAD test
$ git status
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# test
nothing added to commit but untracked files present (use "git add" to track)

注意:请务必记得 git checkout -- <file> 是一个危险的命令。 你对那个文件在本地的任何修改都会消失——Git 会用最近提交的版本覆盖掉它。 除非你确实清楚不想要对那个文件的本地修改了,否则请不要使用这个命令。

shikanon wechat
欢迎您扫一扫,订阅我滴↑↑↑的微信公众号!