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創(chuàng)建分支
示例:stash2個版本代碼球匕,然后查看stash版本列表,應(yīng)用其中一個版本项阴,刪除其中一個版本锌奴。
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參數(shù)只將其它的commit重置到你選定的HEAD,index和working copy中的數(shù)據(jù)不變萧朝。
mixed:
–mixed參數(shù)是將HEAD和index重置到你選定的HEAD垃帅,而working copy不變。
hard:
–hard是將HEAD剪勿,index,working copy同時改變到你規(guī)定的commit上方庭。
示例:拋棄工作區(qū)間不需要改動厕吉,代碼回到上一次提交狀態(tài):
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
# 運(yùn)行 `git rebase` 命令,并指定需要合并的提交范圍械念。如果你想要合并最近的 3 個提交头朱,可以使用以下命令:
git rebase -i HEAD~3
或者
git rebase -i 開始commit 結(jié)束commit
# 強(qiáng)制push以替換遠(yuǎn)程倉的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 比較工作區(qū)與暫存區(qū)
git diff 不加參數(shù)即默認(rèn)比較工作區(qū)與暫存區(qū)
1.2 比較暫存區(qū)與最新本地版本庫(本地庫中最近一次commit的內(nèi)容)
git diff --cached [<path>...]
1.3 比較工作區(qū)與最新本地版本庫
git diff HEAD [<path>...] 如果HEAD指向的是master分支,那么HEAD還可以換成master
1.4 比較工作區(qū)與指定commit-id的差異
git diff commit-id [<path>...]
1.5 比較暫存區(qū)與指定commit-id的差異
git diff --cached [<commit-id>] [<path>...]
1.6 比較兩個commit-id之間的差異
git diff [<commit-id>] [<commit-id>]
1.7 比較兩個分支上最后 commit 的內(nèi)容的差別
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.合并單個提交:當(dāng)我們只想應(yīng)用某個分支上的一個提交到當(dāng)前分支時,可以使用cherry-pick命令希停,而不需要合并整個分支烁巫。
2.修復(fù)bug:當(dāng)我們在一個分支上修復(fù)了一個bug,并希望將這個修復(fù)應(yīng)用到其他分支上時宠能,可以使用cherry-pick命令亚隙。
3.提取特定功能:當(dāng)我們在一個分支上開發(fā)了一個新功能,并希望將該功能應(yīng)用到其他分支上時违崇,可以使用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 將兩個分支中的所有提交都合并到一起,并創(chuàng)建一個新的合并提交入愧,保留了歷史記錄鄙漏。這導(dǎo)致了 Git 歷史記錄中出現(xiàn)多個分支合并點(diǎn)的情況,從而使歷史記錄更加復(fù)雜砂客。
Git rebase 是將一個分支的提交序列“拉直”泥张,并且將其與另一個分支合并。這意味著鞠值,提交歷史看起來好像是一條直線媚创,沒有分叉,因此整個提交歷史看起來更加整潔彤恶,歷史記錄保持相對簡單钞钙。
總的來說,Git rebase 可以提供更整潔的提交歷史声离,但它需要更多的注意力和精細(xì)的操作芒炼,因為它可能導(dǎo)致原有的提交變得不可用。Git merge 則是更為保守的合并方法术徊,它更簡單本刽,但歷史記錄更加復(fù)雜。因此赠涮,選擇哪種方法取決于團(tuán)隊和項目的需求和偏好子寓。
場景:
假設(shè)當(dāng)前我們有master和feature分支,當(dāng)你在專用分支上開發(fā)新 feature 時笋除,然后另一個團(tuán)隊成員在 master 分支提交了新的 commits斜友,這種屬于正常的Git工作場景。
此時是無法push到遠(yuǎn)程倉庫的垃它,需要進(jìn)行分支合并鲜屏,下面來演示git rebase 和 git merge 這兩個命令的差異。
1国拇、git merge
操作:
git checkout feature
git merge master
由上圖可知洛史,git merge 會在 feature 分支中新增一個新的 merge commit,然后將兩個分支的歷史聯(lián)系在一起
- 使用 merge 是很好的方式酱吝,因為它是一種非破壞性的操作虹菲,對現(xiàn)有分支不會以任何方式被更改。
- 另一方面掉瞳,這也意味著 feature 分支每次需要合并上游更改時毕源,它都將產(chǎn)生一個額外的合并提交浪漠。
- 如果master 提交非常活躍霎褐,這可能會嚴(yán)重污染你的 feature 分支歷史記錄址愿。
2. git rebase
git checkout feature
git rebase master
rebase 會將整個 feature 分支移動到 master 分支的頂端,從而有效地整合了所有 master 分支上的提交冻璃。
與 merge 提交方式不同响谓,rebase 通過為原始分支中的每個提交創(chuàng)建全新的 commits 來重寫項目歷史記錄,特點(diǎn)是仍然會在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優(yōu)點(diǎn)是分支代碼合并后不破壞原分支的代碼提交記錄,缺點(diǎn)就是會產(chǎn)生額外的提交記錄并進(jìn)行兩條分支的合并辐烂,
git rebase 優(yōu)點(diǎn)是無須新增提交記錄到目標(biāo)分支遏插,rebase后可以將對象分支的提交歷史續(xù)上目標(biāo)分支上,形成線性提交歷史記錄纠修,進(jìn)行review的時候更加直觀
git merge 如果有多人進(jìn)行開發(fā)并進(jìn)行分支合并胳嘲,會形成復(fù)雜的合并分支圖,比如:
總結(jié):
融合個人分支到主分支的時使用git merge,而不用git rebase
融合主分支到個人分支的時候使用git rebase扣草,可以不污染分支的提交記錄了牛,形成簡潔的線性提交歷史記錄。