Git

Git

Git

打标签

当前commit创建标签

git tag -a v0.1 -m "my first tag"

根据历史commit打

git tag -a v0.2 commitid

检查标签

git show v0.1会跳转到对应的commit

列出标签

1
2
3
liuliancao@liuliancao:~/projects/terraform-module$ git tag
list
v0.1

推送到远程

git push origin –tags推送所有标签 git push origin v0.1推送指定版本标签

git pull && git fetch

git fetch用来检索元数据更新而不更新实际文件 git pull除了做那个还会把远程文件修改更新到本地

git常见命令cheat sheets

copied from gitlab gitlab docs

git configuration

命令片段 说明
git config –global user.name "Your Name" 全局设置用户名
git config –global user.mail "Your Mail" 全局设置邮件
git config –global color.ui auto 全局设置ui

starting a project

命令片段 说明
git init [project name] 初始化一个git repository
git clone [project url] 克隆一个仓库

常用git提交相关

命令片段 说明
git status 查看工作目录的情况
git add [file] 把文件添加到暂存区
git diff [file] 比较当前文件和暂存区的差别
git diff –staged [file] 比较暂存区域和远程仓库的区别
git checkout – [file] 当前working目录的内容重新检出(staged的不会影响),这个操作不可逆
git reset [<path>…] 回退目录到某个状态
git commit 创建一次提交
git rm [file] 把文件从工作目录和暂存区删掉,相当于删除 = rm [file] + git add

如果你有一些commit不想提交了,可以通过git reset [commit sha]回到那个地方,这个时候之后的commit都不会被提交 所以reset的时候注意操作,如果没有保存commit sha, 就得 .git/logs/refs/heads/main 里面找下了

所以为了防止丢失,建议首先git add你的文件,适当的时候commit

保存工作

命令片段 说明
git stash 把暂存区域的放到stash区域, 需要先git add
git stash pop 恢复stash区域
git stash drop 丢掉某个stash区域
 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
➜  first-project git:(main) vim README.md
➜  first-project git:(main) ✗ git status
位于分支 main
您的分支与上游分支 'origin/main' 一致。

未跟踪的文件:
  (使用 "git add <文件>..." 以包含要提交的内容)
	README.md

提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)
➜  first-project git:(main) ✗ git stash
没有要保存的本地修改
➜  first-project git:(main) ✗ git add README.md
➜  first-project git:(main) ✗ git status
位于分支 main
您的分支与上游分支 'origin/main' 一致。

要提交的变更:
  (使用 "git restore --staged <文件>..." 以取消暂存)
	新文件:   README.md
➜  first-project git:(main) ✗ git stash
保存工作目录和索引状态 WIP on main: 9434da1 remove README.md
# later you can do other work like fix bugs and etc.
# after you have done your work, use git stash pop to back to your work
➜  first-project git:(main) git stash pop
位于分支 main
您的分支与上游分支 'origin/main' 一致。

要提交的变更:
  (使用 "git restore --staged <文件>..." 以取消暂存)
	新文件:   README.md

丢弃了 refs/stash@{0}(764b88bff9005b21d9ee42d210e37b9922d1e437)

分支相关

命令片段 说明
git branch [-a] 显示所有的分支,-a表示也包含远程
git branch [branch_name] 创建分支
git rebase [branch_name] 变基,把当前的内容计算好追加到branch_name分支上,而不是合并
git checkout [-b] [branch_name] 切换到分支,-b表示不存在就会创建
git merge [branch_name] 把branch_name分支的内容合并到你的分支上面
git branch -d [branch_name] 删除分支
 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
➜  first-project git:(main) ✗ git branch|cat   
\* main
➜  first-project git:(main) ✗ git branch -a|cat      
\* main
  remotes/origin/HEAD -> origin/main
  remotes/origin/main


➜  first-project git:(main) ✗ git branch liuliancao-branch
➜  first-project git:(main) ✗ git status
位于分支 main
您的分支与上游分支 'origin/main' 一致。

要提交的变更:
  (使用 "git restore --staged <文件>..." 以取消暂存)
	新文件:   README.md

➜  first-project git:(main) ✗ git branch|cat
  liuliancao-branch
\* main
➜  first-project git:(main) ✗ git branch -a|cat
  liuliancao-branch
\* main
  remotes/origin/HEAD -> origin/main
  remotes/origin/main

关于rebase

加入现在需要开发一个hello world功能,我们创建feature-hello-world-rebase分支,功能开发完毕以后需要合并到main分支

创建分支,在分支开发完毕

 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
➜  first-project git:(main) git checkout -b feature-hello-world-rebase
切换到一个新分支 'feature-hello-world-rebase'
➜  first-project git:(feature-hello-world-rebase) ls
README.md  test-resets
➜  first-project git:(feature-hello-world-rebase) ✗ cat hello-world.txt
hello world!
➜  first-project git:(feature-hello-world-rebase) ✗ git add hello-world.txt 
➜  first-project git:(feature-hello-world-rebase) ✗ git commit -m 'feature: add hello world!'
[feature-hello-world-rebase d8f4179] feature: add hello world!
 1 file changed, 1 insertion(+)
 create mode 100644 hello-world.txt
➜  first-project git:(feature-hello-world-rebase) git push
致命错误:当前分支 feature-hello-world-rebase 没有对应的上游分支。
为推送当前分支并建立与远程上游的跟踪,使用

    git push --set-upstream origin feature-hello-world-rebase

为了让没有追踪上游的分支自动配置,参见 'git help config' 中的 push.autoSetupRemote。

➜  first-project git:(feature-hello-world-rebase) git push --set-upstream origin feature-hello-world-rebase
枚举对象中: 4, 完成.
对象计数中: 100% (4/4), 完成.
使用 8 个线程进行压缩
压缩对象中: 100% (2/2), 完成.
写入对象中: 100% (3/3), 338 字节 | 338.00 KiB/s, 完成.
总共 3(差异 0),复用 0(差异 0),包复用 0
remote: 
remote: To create a merge request for feature-hello-world-rebase, visit:
remote:   https://gitlab.com/liuliancao1/first-project/-/merge_requests/new?merge_request%5Bsource_branch%5D=feature-hello-world-rebase
remote: 
To gitlab.com:liuliancao1/first-project.git
 * [new branch]      feature-hello-world-rebase -> feature-hello-world-rebase
分支 'feature-hello-world-rebase' 设置为跟踪 'origin/feature-hello-world-rebase'

rebase前我们先放点东西到main

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
➜  first-project git:(feature-hello-world-rebase) git checkout main
切换到分支 'main'
您的分支与上游分支 'origin/main' 一致。
➜  first-project git:(main) ls
README.md  test-resets
➜  first-project git:(main) vim README.md 
➜  first-project git:(main) ✗ git add README.md
➜  first-project git:(main) ✗ git commit -m 'add before rebase'
[main 8126185] add before rebase
 1 file changed, 1 insertion(+), 1 deletion(-)
➜  first-project git:(main) git push
枚举对象中: 5, 完成.
对象计数中: 100% (5/5), 完成.
使用 8 个线程进行压缩
压缩对象中: 100% (2/2), 完成.
写入对象中: 100% (3/3), 296 字节 | 296.00 KiB/s, 完成.
总共 3(差异 0),复用 0(差异 0),包复用 0
To gitlab.com:liuliancao1/first-project.git
   7b42be5..8126185  main -> main

qa在分支下测试ok开始执行合并,qa可以选择在main分支 git merge feature-hello-world-rebase 或者 git rebase feature-hello-wrold-rebase 我们试试rebase的效果

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
➜  first-project git:(main) git rebase feature-hello-world-rebase 
成功变基并更新 refs/heads/main。
➜  first-project git:(main) git log --graph|cat
\* commit a3f951dc003df253f76dfa14bbfa452da5a05f8c
| Author: liuliancao <liuliancao@gmail.com>
| Date:   Thu Feb 29 14:05:17 2024 +0800
| 
|     add before rebase
| 
\* commit d8f417986204ecff7fc8e869623f1beabd8849e1
| Author: liuliancao <liuliancao@gmail.com>
| Date:   Thu Feb 29 14:02:19 2024 +0800
| 
|     feature: add hello world!
|

这里发现rebase把hello world的共塞进来了,如果是merge会怎么样呢

 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
➜  first-project git:(main) git reset --hard origin/main
HEAD 现在位于 8126185 add before rebase
➜  first-project git:(main) git merge feature-hello-world-rebase 
Merge made by the 'ort' strategy.
 hello-world.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 hello-world.txt
➜  first-project git:(main) git log --graph|cat
\*   commit 462b2d7c15a24af1ec6fded255be8707710a8ecb
|\  Merge: 8126185 d8f4179
| | Author: liuliancao <liuliancao@gmail.com>
| | Date:   Thu Feb 29 14:14:24 2024 +0800
| | 
| |     Merge branch 'feature-hello-world-rebase'
| | 
| * commit d8f417986204ecff7fc8e869623f1beabd8849e1
| | Author: liuliancao <liuliancao@gmail.com>
| | Date:   Thu Feb 29 14:02:19 2024 +0800
| | 
| |     feature: add hello world!
| | 
\* | commit 812618508965bd026693fbf288d8b71d89037b3a
|/  Author: liuliancao <liuliancao@gmail.com>
|   Date:   Thu Feb 29 14:05:17 2024 +0800
|   
|       add before rebase
|

我们发现有了一次交叉,并且有merge的一次提交看起来非常不美观

查看inspect相关

命令片段 说明
git log [-n count] 显示提交记录 -n表示最近多少次的提交记录
git log –oneline –graph –decorate 图形化展示
git log ref.. 显示某个分支的提交
git reflog 查看操作记录

加了..可以查看某个分支是否合并了当前分支的内容,这里我切到main发现feature-hello-world-rebase并没有merge或者合并main的内容到分支 而feature-hello-world-rebase已经合并了main的分支,因为查看是空

当我切到特性分支把main的内容rebase过来以后,在main下就发现没有未被对方merge的提交了

所以这个功能可以用于快速查看对方分支是否把自己的内容都merge过去了

可以在特性分支上 git ref main..以查看是否有漏合并的

反方向可以git ref ..特性分支

 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
➜  first-project git:(main) git log feature-hello-world-rebase..|cat
commit 462b2d7c15a24af1ec6fded255be8707710a8ecb
Merge: 8126185 d8f4179
Author: liuliancao <liuliancao@gmail.com>
Date:   Thu Feb 29 14:14:24 2024 +0800

    Merge branch 'feature-hello-world-rebase'

commit 812618508965bd026693fbf288d8b71d89037b3a
Author: liuliancao <liuliancao@gmail.com>
Date:   Thu Feb 29 14:05:17 2024 +0800

    add before rebase
➜  first-project git:(main) git checkout feature-hello-world-rebase 
切换到分支 'feature-hello-world-rebase'
您的分支与上游分支 'origin/feature-hello-world-rebase' 一致。
➜  first-project git:(feature-hello-world-rebase) git status
位于分支 feature-hello-world-rebase
您的分支与上游分支 'origin/feature-hello-world-rebase' 一致。

无文件要提交,干净的工作区
➜  first-project git:(feature-hello-world-rebase) git log main..
➜  first-project git:(feature-hello-world-rebase) git log main..|cat


# rebase and check
➜  first-project git:(feature-hello-world-rebase) git rebase main
成功变基并更新 refs/heads/feature-hello-world-rebase。
➜  first-project git:(feature-hello-world-rebase) git checkout main
切换到分支 'main'
您的分支领先 'origin/main'2 个提交。
  (使用 "git push" 来发布您的本地提交)
➜  first-project git:(main) git log feature-hello-world-rebase..
➜  first-project git:(main) git log feature-hello-world-rebase..|cat

reflog

1
2
3
4
5
6
7
➜  first-project git:(main) git reflog|cat
462b2d7 HEAD@{0}: checkout: moving from feature-hello-world-rebase to main
462b2d7 HEAD@{1}: rebase (finish): returning to refs/heads/feature-hello-world-rebase
462b2d7 HEAD@{2}: rebase (start): checkout main
d8f4179 HEAD@{3}: checkout: moving from main to feature-hello-world-rebase
462b2d7 HEAD@{4}: merge feature-hello-world-rebase: Merge made by the 'ort' strategy.
8126185 HEAD@{5}: reset: moving to origin/main

标签相关

命令片段 说明
git tag 显示标签
git tag [name] [commit sha] 给某个commit打一个标签引用
git tag -a [name] [commit_sha] 创建一个标签对象
git tag -d [name] 删除一个标签

标签相关 标签主要用于打一些release等特殊情况,方便过滤

 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
➜  first-project git:(main) git tag|cat
➜  first-project git:(main) git tag release-v0.0.1 
➜  first-project git:(main) git tag|cat
release-v0.0.1
➜  first-project git:(main) vim README.md 
➜  first-project git:(main) ✗ git add README.md 
➜  first-project git:(main) ✗ git commit -m 'add something'
[main 677ab22] add something
 1 file changed, 1 insertion(+)
➜  first-project git:(main) git tag -a release-v0.0.2
➜  first-project git:(main) git tag |cat
release-v0.0.1
release-v0.0.2
➜  first-project git:(main) git log --decorate -n 2|cat
commit 677ab22969049ba86c95c05734ea5f377efc0698 (HEAD -> main, tag: release-v0.0.2)
Author: liuliancao <liuliancao@gmail.com>
Date:   Thu Feb 29 14:32:29 2024 +0800

    add something

commit 462b2d7c15a24af1ec6fded255be8707710a8ecb (tag: release-v0.0.1, feature-hello-world-rebase)
Merge: 8126185 d8f4179
Author: liuliancao <liuliancao@gmail.com>
Date:   Thu Feb 29 14:14:24 2024 +0800

    Merge branch 'feature-hello-world-rebase'

回滚变更

命令片段 说明
git reset [–hard] [target reference] 把当前分支切换到目标引用,如果–hard,那么当前编辑的内容未暂存的将会没有
git revert [commit sha] 回滚某个变更

这里加入你改了一些东西,后来发现没啥意义想回到之前的情况,你可以直接reset就切回到刚开始的情况了 当然如果个别文件你也可以checkout

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
➜  first-project git:(main) ls
hello-world.txt  README.md  test-resets
➜  first-project git:(main) vim hello-world.txt 
➜  first-project git:(main) ✗ cat hello-world.txt
hello world!

hello world again!
➜  first-project git:(main) ✗ git reset 
重置后取消暂存的变更:
M	hello-world.txt
➜  first-project git:(main) ✗ cat hello-world.txt 
hello world!

hello world again!
➜  first-project git:(main) ✗ git reset --hard 
HEAD 现在位于 677ab22 add something
➜  first-project git:(main) cat hello-world.txt 
hello world!

git revert,这里发现revert和rebase也是差不多的可能存在conflict,这里注意conflict以后只需要add就好了,不需要commit

 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
➜  first-project git:(main) git revert 812618508965bd026693fbf288d8b71d89037b3a
自动合并 README.md
冲突(内容):合并冲突于 README.md
错误:不能还原 8126185... add before rebase
提示:解决所有冲突之后,用 "git add/rm <路径规格>" 标记它们,
提示:然后执行 "git revert --continue"。您也可以执行
提示:"git revert --skip" 命令跳过这个提交。如果想要终止执行并回到
提示:执行 "git revert" 之前的状态,执行 "git revert --abort"➜  first-project git:(main) ✗ git status
位于分支 main
您的分支与上游分支 'origin/main' 一致。

您在执行反转提交 8126185 的操作。
  (解决冲突并执行 "git revert --continue"  (使用 "git revert --skip" 跳过此补丁)
  (使用 "git revert --abort" 以取消反转提交操作)

未合并的路径:
  (使用 "git restore --staged <文件>..." 以取消暂存)
  (使用 "git add <文件>..." 标记解决方案)
	双方修改:   README.md

修改尚未加入提交(使用 "git add" 和/或 "git commit -a"➜  first-project git:(main) ✗ vim README.md
➜  first-project git:(main) ✗ git add README.md
➜  first-project git:(main) ✗ git revert --continue 
[main 284ac33] Revert "add before rebase"
 1 file changed, 1 insertion(+), 2 deletions(-)

同步仓库

命令片段 说明
git fetch [remote] 获取远程更新,但不执行更新
git fetch –prune [remote] prune是修剪,把远程不存在的标签、分支删掉
git pull [remote] 获取远程分支内容
git push [–tags] 推送到远程分支或者标签
git push -u [remote] [branch] 把推送到远程分支

git fetch是一个比较好的习惯,一般如果你直接pull或者merge之前先检查下变更了啥,是否要更新 git fetch是把远程的信息拉下来,但是暂时不处理,需要手动rebase或者merge

git pull相当于git fetch && git merge

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# 远程修改或者别人提交了内容
➜  first-project git:(main) git fetch origin main
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
展开对象中: 100% (3/3), 329 字节 | 329.00 KiB/s, 完成.
来自 gitlab.com:liuliancao1/first-project
 * branch            main       -> FETCH_HEAD
   284ac33..445c93a  main       -> origin/main
# 此时还是老的内容
➜  first-project git:(main) cat README.md 
test
# log里面没有新commit
➜  first-project git:(main) git log main
# FETCH_HEAD和默认都会有新的commit
➜  first-project git:(main) git log FETCH_HEAD 
# 执行rebase或者merge就能看到新内容
➜  first-project git:(main) git rebase
成功变基并更新 refs/heads/main。

忽略文件gitignore

可以发现.gitignore里面匹配的内容就不会自动到status记录里面

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
➜  first-project git:(main) vim .gitignore
➜  first-project git:(main) ✗ mkdir logs
➜  first-project git:(main) ✗ touch logs/aaa.log
➜  first-project git:(main) ✗ git status
位于分支 main
您的分支与上游分支 'origin/main' 一致。

未跟踪的文件:
  (使用 "git add <文件>..." 以包含要提交的内容)
	.gitignore

提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)
➜  first-project git:(main) ✗ git add .gitignore
➜  first-project git:(main) ✗ cat .gitignore 
logs/*