Git命令实战操作

git stash

保存没有提交的修改

git stash暂存
git stash pop 使用最近一次暂存
git stash save "xxx" 暂存时添加暂存信息
git stash list 查看暂存列表
git stash apply stash@{X} 回到某个暂存版本
git stash drop stash@{X} 删除某个暂存版本
git stash show stash@{X} 查看暂存版本详情
git stash branch 从最新的stash创建分支

示例:stash2个版本代码,然后查看stash版本列表,应用其中一个版本,删除其中一个版本。

libo@libodeMacBook-Pro AlgorithmDeep % git stash list          
libo@libodeMacBook-Pro AlgorithmDeep % git stash save "添加一个功能1"
Saved working directory and index state On master: 添加一个功能1
libo@libodeMacBook-Pro AlgorithmDeep % git stash save "删除了一个功能2"
Saved working directory and index state On master: 删除了一个功能2
libo@libodeMacBook-Pro AlgorithmDeep % git stash list
stash@{0}: On master: 删除了一个功能2
stash@{1}: On master: 添加一个功能1
libo@libodeMacBook-Pro AlgorithmDeep % git stash apply stash@{1}
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   .idea/vcs.xml

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:   app/src/main/java/com/example/algorithmdeep/Practise.java

libo@libodeMacBook-Pro AlgorithmDeep % git stash drop stash@{0}
Dropped stash@{0} (3c4d22d1252eb2f067ad2f30cff69f72dfff3672)
libo@libodeMacBook-Pro AlgorithmDeep % git stash list
stash@{0}: On master: 添加一个功能1
git reset

git reset 命令格式为:
git reset [ --soft | --mixed | --hard ] [< commitid >]

soft:
–soft参数只将其它的commit重置到你选定的HEAD,index和working copy中的数据不变。
mixed:
–mixed参数是将HEAD和index重置到你选定的HEAD,而working copy不变。
hard:
–hard是将HEAD,index,working copy同时改变到你规定的commit上。

示例:抛弃工作区间不需要改动,代码回到上一次提交状态:

libo@libodeMacBook-Pro AlgorithmDeep % git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   .idea/vcs.xml

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:   app/src/main/java/com/example/algorithmdeep/Practise.java

libo@libodeMacBook-Pro AlgorithmDeep % git reset --hard
HEAD is now at 828b07b init commit
git log
  • git log 查看各次提交信息
libo@libodeMacBook-Pro AlgorithmDeep % git log
commit 4a0a889808b21db5ec2c056209ceaf1bd7e34abf (HEAD -> master)
Author: libo <libo31@xiaomi.com>
Date:   Sun Nov 26 11:10:09 2023 +0800

    新增detectCycle代码

commit 8804579282019db1def1d4ec5a0970a445c18daa
Author: libo <libo31@xiaomi.com>
Date:   Sun Nov 26 11:09:05 2023 +0800

    新增levelOrder代码

commit 828b07b94e9598f5442f452f734bcecbc3cdfd3a
Author: libo <libo31@xiaomi.com>
Date:   Sun Nov 26 10:53:27 2023 +0800

    init commit

  • git log --oneline 选项来查看历史记录的简洁的版本
libo@libodeMacBook-Pro AlgorithmDeep % git log --oneline
4a0a889 (HEAD -> master) 新增detectCycle代码
8804579 新增levelOrder代码
828b07b init commit
合并多个commit

方法:git rebase

# 查看前10个commit
git log -10
# 运行 `git rebase` 命令,并指定需要合并的提交范围。如果你想要合并最近的 3 个提交,可以使用以下命令:
git rebase -i HEAD~3
或者
git rebase -i 开始commit 结束commit
# 强制push以替换远程仓的commitID
git push --force

参考:https://blog.csdn.net/wangdawei_/article/details/131669124

git rebase -i HEAD~2    
pick 8804579 新增levelOrder代码
pick 4a0a889 新增detectCycle代码
# Rebase 828b07b..4a0a889 onto 828b07b (2 commands)

Successfully rebased and updated refs/heads/master.
git diff

用于比较两次修改的差异

1.1 比较工作区与暂存区
git diff 不加参数即默认比较工作区与暂存区

1.2 比较暂存区与最新本地版本库(本地库中最近一次commit的内容)
git diff --cached [<path>...]

1.3 比较工作区与最新本地版本库
git diff HEAD [<path>...] 如果HEAD指向的是master分支,那么HEAD还可以换成master

1.4 比较工作区与指定commit-id的差异
git diff commit-id [<path>...]

1.5 比较暂存区与指定commit-id的差异
git diff --cached [<commit-id>] [<path>...]

1.6 比较两个commit-id之间的差异
git diff [<commit-id>] [<commit-id>]

1.7 比较两个分支上最后 commit 的内容的差别
git diff <分支名1> <分支名2>

参考:https://www.runoob.com/git/git-diff.html

git commit --amend

合并这次提交到上一次commit里面,并且可以修改commit message。

新增detectCycle代码

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Sun Nov 26 11:10:09 2023 +0800
#
# On branch master
# No commands done.
# Next command to do (1 remaining command):
#    pick 4a0a889 新增detectCycle代码
# You are currently editing a commit during a rebase.
#
# Changes to be committed:
#       modified:   app/src/main/java/com/example/algorithmdeep/Practise.java
:wq
git cherry-pick

cherry-pick命令常用于以下场景:
1.合并单个提交:当我们只想应用某个分支上的一个提交到当前分支时,可以使用cherry-pick命令,而不需要合并整个分支。
2.修复bug:当我们在一个分支上修复了一个bug,并希望将这个修复应用到其他分支上时,可以使用cherry-pick命令。
3.提取特定功能:当我们在一个分支上开发了一个新功能,并希望将该功能应用到其他分支上时,可以使用cherry-pick命令。

git cherry-pick <commit>

示例:在主分支新增了提交,在feature分支使用git cherry-pick <commit>去拉取合并这一个提交。

libo@libodeMacBook-Pro AlgorithmDeep % git branch feature
libo@libodeMacBook-Pro AlgorithmDeep % git commit -a -m "主分支提交功能"  
[master 00e8af2] 主分支提交功能
 1 file changed, 4 insertions(+)
libo@libodeMacBook-Pro AlgorithmDeep % git checkout feature
Switched to branch 'feature'
libo@libodeMacBook-Pro AlgorithmDeep % git cherry-pick 00e8af2
[feature e0017ec] 主分支提交功能
 Date: Sun Nov 26 11:40:27 2023 +0800
 1 file changed, 4 insertions(+)
git merge和git rebase

git rebase和git merge这两个命令都旨在将更改代码从一个分支合并到另一个分支,但二者的合并方式却有很大的不同。

Git merge 将两个分支中的所有提交都合并到一起,并创建一个新的合并提交,保留了历史记录。这导致了 Git 历史记录中出现多个分支合并点的情况,从而使历史记录更加复杂。
Git rebase 是将一个分支的提交序列“拉直”,并且将其与另一个分支合并。这意味着,提交历史看起来好像是一条直线,没有分叉,因此整个提交历史看起来更加整洁,历史记录保持相对简单。

总的来说,Git rebase 可以提供更整洁的提交历史,但它需要更多的注意力和精细的操作,因为它可能导致原有的提交变得不可用。Git merge 则是更为保守的合并方法,它更简单,但历史记录更加复杂。因此,选择哪种方法取决于团队和项目的需求和偏好。

场景:

假设当前我们有master和feature分支,当你在专用分支上开发新 feature 时,然后另一个团队成员在 master 分支提交了新的 commits,这种属于正常的Git工作场景。

此时是无法push到远程仓库的,需要进行分支合并,下面来演示git rebase 和 git merge 这两个命令的差异。

1、git merge

操作:

git checkout feature
git merge master

由上图可知,git merge 会在 feature 分支中新增一个新的 merge commit,然后将两个分支的历史联系在一起

  • 使用 merge 是很好的方式,因为它是一种非破坏性的操作,对现有分支不会以任何方式被更改。
  • 另一方面,这也意味着 feature 分支每次需要合并上游更改时,它都将产生一个额外的合并提交。
  • 如果master 提交非常活跃,这可能会严重污染你的 feature 分支历史记录。
2. git rebase
git checkout feature
git rebase master
  • rebase 会将整个 feature 分支移动到 master 分支的顶端,从而有效地整合了所有 master 分支上的提交。

  • 与 merge 提交方式不同,rebase 通过为原始分支中的每个提交创建全新的 commits 来重写项目历史记录,特点是仍然会在feature分支上形成线性提交

  • rebase的主要好处就是历史记录更清晰,没有不必要的合并提交,提交历史看起来好像是一条直线,没有分叉。

libo@libodeMacBook-Pro AlgorithmDeep % git checkout feature
Switched to branch 'feature'
libo@libodeMacBook-Pro AlgorithmDeep % git rebase master
Auto-merging app/src/main/java/com/example/algorithmdeep/Practise.java
CONFLICT (content): Merge conflict in app/src/main/java/com/example/algorithmdeep/Practise.java
error: could not apply 4a0a889... 新增detectCycle代码
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 4a0a889... 新增detectCycle代码
Could not apply 53a0a17... feature分支提交功能3
libo@libodeMacBook-Pro AlgorithmDeep % git rebase --continue
app/src/main/java/com/example/algorithmdeep/Practise.java: needs merge
You must edit all merge conflicts and then
mark them as resolved using git add
libo@libodeMacBook-Pro AlgorithmDeep % git add .
libo@libodeMacBook-Pro AlgorithmDeep % git rebase --continue
[detached HEAD 17fcbb1] feature分支提交功能3
 1 file changed, 5 insertions(+)
Successfully rebased and updated refs/heads/feature.

rebase之后,两个分支的两个条线,就融合成了一条提交线:


如何选择git merge和git rebase?

git merge优点是分支代码合并后不破坏原分支的代码提交记录,缺点就是会产生额外的提交记录并进行两条分支的合并,

git rebase 优点是无须新增提交记录到目标分支,rebase后可以将对象分支的提交历史续上目标分支上,形成线性提交历史记录,进行review的时候更加直观

git merge 如果有多人进行开发并进行分支合并,会形成复杂的合并分支图,比如:

总结:
融合个人分支到主分支的时使用git merge,而不用git rebase
融合主分支到个人分支的时候使用git rebase,可以不污染分支的提交记录,形成简洁的线性提交历史记录。

参考:
https://joyohub.com/2020/04/06/git-rebase/

https://www.bilibili.com/video/BV1Xb4y1773F/?spm_id_from=333.337.search-card.all.click&vd_source=40c24e77b23dc2e50de2b7c87c6fed59

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容