git 代码没了,git rebase 合并提交记录,git stash
xx
- 問題
- git合并提交記錄
- 創建提交記錄
- 合并提交記錄
- rebase有沖突
- 合并后的本地路徑提交到遠程
- 其中的參數
- pick
- 改變提交 5.txt 和 4.txt 的順序
- 刪除某一個提交
- reword
- 修改提交信息
- edit
- 兩個提交之間 再加提交
- 想要單純的修改這次提交內容和消息
- squash
- fixup
- exec
- git rebase -i HEAD~3 最后的數字寫錯了
- git stash
- 實例
- bug出現
- 查看修改
- 繼續開發
- git stash深入一點
- 修改存儲到什么位置了?
- stash 的存儲的名稱是怎么來的,可以修改嗎?
- 從stash創建分支
- 注意
問題
lhf-dev沒有 add 切換到dev,pull,導致 lhf-Dev git status 也沒有沒有add之前的代碼了。
切換到lhf-dev,ctrl+z undo reload from disk
就找回了
git合并提交記錄
參考多個提交記錄合并成一個提交記錄
在使用git進行版本管理的過程中,開發人員代碼的提交可能需要在多個分支之間進行切換,每個開發人員提交代碼的習慣也是不一樣的,有的喜歡開發完成提交,有個喜歡半個小時提交一次……有些時候我們并不希望在另一個分支上看到當前分支的多次提交記錄,只希望將多個提交記錄合并成一個記錄,達到美化commit history的效果
創建提交記錄
首先在分支上創建了3個提交記錄,如下圖:
合并提交記錄
假設需要合并這3個提交記錄,執行命令
git rebase -i HEAD~3會有如下提示:
pick是rebase時的指令,具體我們還可以使用如下指令:
選擇pick指令,git會應用這個提交,以同樣的提交信息(commit message)保存提交 選擇reword指令,git會應用這個提交,但需要重新編輯提交信息 選擇edit指令,git會應用這個提交,但會因為amending而終止 ** 選擇squash指令,git會應用這個提交,但會與上一次的提交合并 選擇fixup指令,git會應用這個提交,但會丟掉提交日志 選擇exec指令,git會在shell中運行這個命令如果合并成功會打開另外一個文件文件,在這里我們輸入這次合并時的提交記錄信息。
如果合并有沖突,在解決沖突后需要輸入
git add . git rebase --continue如果不想合并了,放棄合并的指令是
git rebase --abort接下來,如果我們修改提示文件:
pick 3e60dd4 創建合并提交記錄 s 627c7d7 修改合并提交記錄 表示合并到3e60dd4版本 s 3a259d9 完成合并提交記錄 表示合并到627c7d7版本
如果我們不想修改任何信息,保存即可,也可以修改最終的提交信息后再保存。
然后我們再看下這時的git history
* 44c536b - (HEAD -> feature) 合并提交記錄完成 (4 minutes ago) <Blackfat>可以看到3條提交記錄,已經合并成了一條記錄,并且修改了最終的提交信息。
rebase有沖突
$ git rebase -i HEAD~2Auto-merging 沖突文件 CONFLICT (content): Merge conflict in 沖突文件 error: could not apply 版本id... 版本提交名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 版本id... 版本提交名上面意思就是 首先處理沖突,然后 git add . ,然后 git rebase --continue
或者跳過合并 git rebase --skip
或者終止合并 git rebase --abort
上面意思就是說 解決之后如果沒有其他操作需要commit,就 git add 或者 git commit -a
如果直接 git rebase --continue 就還是提示讓 git add .$ git rebase --continue 沖突文件: needs merge You must edit all merge conflicts and then mark them as resolved using git add$ git add . $ git rebase --continue [detached HEAD 版本id] vim編輯rebase的提交名Date: Tue Oct 26 17:42:17 2021 +08002 files changed, 25 insertions(+), 13 deletions(-) Successfully rebased and updated refs/heads/dev.總結:首先處理沖突,然后 git add . ,然后 git rebase --continue
合并后的本地路徑提交到遠程
合并完本地記錄后
git push -f這條指令將本地倉庫合并記錄推送支遠端倉庫,如果沒有-f的話,系統會提示你,當前記錄不是最新的,無法提交, -f 是force的意思,強制提交。
其中的參數
pick
pick只是意味著包括提交。重新進行命令時,重新安排pick命令的順序會更改提交的順序。如果選擇不包括提交,則應刪除整行
只要不動pick的 順序,就代表什么都不做
改變提交 5.txt 和 4.txt 的順序
pick 8b485bb add 4 pick a75ed74 add 5vi編輯器,首先Esc ,進入命令模式,移動到第一行 按dd,本行就被剪切,pick a75ed74 add 5就變成了第一行,接著按 p剛剛剪切的就成了第二行,快速交換順序 更改為pick a75ed74 add 5 pick 8b485bb add 4接著 Esc,:wq 保存退出git log查看,4 和 5 的順序改變了
刪除某一個提交
pick 8b485bb add 4 pick a75ed74 add 5更改為pick 8b485bb add 4接著 Esc,:wq 保存退出reword
該reword命令與相似pick,但是使用后,重新設置過程將暫停并為您提供更改提交消息的機會。提交所做的任何內容更改均不受影響,只是更改了提交名字
修改提交信息
pick 9cd34c4 add 2 pick 63ce9fb add 3 pick 575fd8b add 5改為r 9cd34c4 add 2 修改 9cd34c4 的提交信息 pick 63ce9fb add 3 pick 575fd8b add 5接著 Esc,:wq 保存退出git會說 開始執行,接著彈出一個編輯窗口add 2 修改這里即可# Please enter the commit message for your changes. Lines starting ......edit
如果您選擇edit提交,則將有機會修改提交,這意味著您可以完全添加或更改提交。您還可以進行更多提交,然后再繼續進行變基。這使您可以將大型提交拆分為較小的提交,或者刪除在提交中所做的錯誤更改。
兩個提交之間 再加提交
我們要在 add 3 和 add 5 之間 添加一條提交
git rebase -i HEAD~2pick 6934312 add 3 pick 5ce6dde add 5# Rebase 7f9d45d..5ce6dde onto 7f9d45d (2 command(s)) # ....改為e 6934312 add 3 pick 5ce6dde add 5可以看到,我們的master分支多了REBASE-i 1/2
$ git rebase -i HEAD~2 Stopped at 6934312135c150bf74bead26e371df1443273ca4... add 3 You can amend the commit now, withgit commit --amendOnce you are satisfied with your changes, rungit rebase --continue---------------這里-------------- xxxxxx MINGW32 ~/Desktop/git-demo (master|REBASE-i 1/2)嘗試做一些修改,給3.txt 增加一些內容,然后提交
git add 3.txtgit commit -m "edit 3.txt" [detached HEAD 7262a57] edit 3.txt1 file changed, 1 insertion(+)恢復rebase
git rebase --continue Successfully rebased and updated refs/heads/master.git log 查看,在 add 5 和 add 3 中間 增加了我們剛剛的修改
想要單純的修改這次提交內容和消息
參照上面的做到這一步,我們選擇提交的方式 加一個參數 git commit --amend修改
git add 3.txtgit commit --amend# 這樣 就不會在多出一次提交 # 本次對 3.txt的修改會記錄 到 add 3 這次提交記錄中接著結束這次 rebase
git rebase --continue Successfully rebased and updated refs/heads/master.squash
該命令使您可以將兩個或多個提交合并為一個提交。提交被壓縮到其上方的提交中。Git使您有機會編寫描述這兩個更改的新提交消息。
參考上面git合并提交記錄
fixup
這類似于squash,但是要合并的提交已丟棄其消息。提交僅合并到其上方的提交中,并且較早提交的消息用于描述這兩個更改。
git rebase -i HEAD~2pick 7f9d45d add 2 ~ new comment pick 311adc9 add 3# Rebase 77bd0eb..311adc9 onto 77bd0eb (2 command(s)) # ---------------------- # 變更為 # -----------------------pick 7f9d45d add 2 ~ new comment f 311adc9 add 3# 保存exec
這使您可以對提交運行任意的Shell命令。
git rebase -i HEAD~3# 彈出編輯框 #---------------------------- pick 81fe4d0 添加test2.txt和test3.txt pick 77bd0eb add 1 pick e7c68b8 add 2 ~ new comment# Rebase 258a059..e7c68b8 onto 258a059 (3 command(s)) #....# ---------------- # 加一行 命令 # --------------- x echo "Hello is echo do ......." pick 81fe4d0 添加test2.txt和test3.txt pick 77bd0eb add 1 pick e7c68b8 add 2 ~ new comment## 執行了我們剛剛鍵入的命令 Executing: echo "Hello is echo do ......." Hello is echo do ....... Successfully rebased and updated refs/heads/master.git rebase -i HEAD~3 最后的數字寫錯了
或者 git rebase后怎么恢復 / 撤銷rebase / rebase 報沖突了
如果 git rebase -i HEAD~3 發現最后的數字寫錯了,可以不修改前面的pick,就會正常提交 保持 每個提交記錄的 pick cdsada3n32q 然后退出編輯模式后,放棄合并 git rebase --abort如果想要放棄當前rebase操作,用 git rebase --abort 如果沖突已經解決,先add沖突文件,即 git add filename 之后, git rebase --continuegit stash
一、git pull 拉代碼的時候,或者切換分支的時候,防止沖突和不便,,會用到git stash,將工作區內容暫存起來。
比如:為了fix 一個bug, 先stash, 使返回到自己上一個commit, 改完bug之后再stash pop, 繼續原來的工作。怎么辦:
git stash會把所有未提交的修改(包括暫存的和非暫存的)都保存起來,stash是本地的,不會通過git push命令上傳到git server上
git stash 備份當前工作區的內容,保存到git 棧中,從最近的一次commit中讀取相關內容 git pull 或者做其他的工作 git stash pop 從git棧中獲取到最近一次stash進去的內容,恢復工作區的內容。。獲取之后,會刪除棧中對應的stash。。 git stash save message 自定義保存message由于可能會stash多次,git使用棧管理,我們可以使用git stash list查看所有的stash git stash list 顯示git棧中的所有工作區內容的備份git stash apply stash@{1},就可以把版本號為stash@{1}的備份取出,不會刪除對應的stash。。0為最新版本git stash clear 清空git棧,刪除所有緩存的stash獲取stash
git stash pop 是彈出棧頂的一個 stash ,也就是最后一次存儲的 stash,在存儲多個stash ,想取出非棧頂的一個的情況下,是不適用的。這個時候要使用:
如果得到這結果說明你的stash 是沒有東西的
移除某一個stash
$ git stash list stash@{0}: WIP on master: 049d078 added the index file$ git stash drop stash@{0} Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43)$ git stash drop stash@{0} 這是刪除第一個隊列 報錯的話就 $ git stash drop 0 這個即可git stash 不會緩存,在工作目錄中新的文件(untracked files)、被忽略的文件(ignored files)
還可以git reset --hard放棄本地修改,然后就可以git pull了。。但是不推薦使用git reset --hard指令,實在是太危險啦!
二、但是git stash pop取出備份的時候也會出現沖突
比如,有個文件login.java,,你修改了一段代碼,git stash保存以后,你從服務器上繼續git pull了別人的代碼
如果此時,別人的代碼也修改了login.java。。。
此時當我們使用git stash pop 的時候,就會發生沖突,因為我們的修改不是基于最新的pull下來的文件的基礎上。。所以git很難判斷,
解決方法:
備份我們修改后的文件,,刪除程序文件中我們所做的修改,重新pull,,然后在用我們備份好的文件替換掉,,再push上去即可。。另一種就是上面說的git reset --hard了,,,,直接忽略本地的修改。。。但這樣明顯太危險!實例
此時我在 feature_666 分支,非常聚精會神加持高專注地實現一個功能 666 模塊,簡直鍵盤如飛的編寫代碼~~~
然后這時,客戶反饋出一個 bug , 非常嚴重,必須立馬解決,優先級為 0 !!!
于是,我需要去到 release 分支去 checkout 新的分支去工作了,但是 666 功能還沒完成怎么辦?
此時我面臨著一個選擇題:
A:提交后切換,代碼保存到分支 feature_666,卻產生一個無意義的提交
B:不提交直接切換,然而這個選項根本沒人會選。
是不是很難選,此時,別忘記還有 C 選項!
C:使用 git stash , 將當前修改(未提交的代碼)存入緩存區,切換分支修改 bug ,回來再通過 git stash pop 取出來。
================================================================
bug出現
上一個 commit 的時候,代碼快照是這個樣子的
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);String s = "大家好,我是段小憨";} }此時的我在寫代碼如下:
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);String s = "大家好,我是段小憨";String s1 = "我現在在寫一個超級厲害的功能,但是我還沒寫完,甚至還有點地方在報錯";} }代碼到此處,緊急 bug 出現了,一秒都不能等, 選擇下列操作
git stash //將修改存儲到暫存區,工作區會刪除相對于上一個提交版本的修改 git checkout <bug_branch>
暫存后的工作區代碼會恢復到最后一次提交時的代碼:
查看修改
如果你有丟失代碼的經歷,肯定會對這個之前沒接觸的新命令不放心,那么怎么確定你操作成功了呢?
git stash show //查看剛才暫存的修改繼續開發
現在 bug 改完了,要重新回來開發了,取出修改
git checkout <feture_branch> //切換剛才功能開發的分支 git stash pop //取出修改
取出修改后的工作區代碼為:
git stash深入一點
修改存儲到什么位置了?
當我們使用 git init給項目添加版本控制的時候,會在項目路徑下生成一個 .git 隱藏文件夾。.git 中存儲著版本管理的所有信息。
.git/refs/stash 中,存儲的是最后一個 stash 對應的節點指針
同樣,在 .git/log/refs/stash 中可以看到我們全部的 stash 記錄信息
我們來嘗試一下修改文件,然后再次使用 git stash ,此時我們有個兩個 暫存修改,那么怎么查看呢?
git stash list //查看暫存區的所有暫存修改記錄
此時你有沒有發現,這兩個的名稱是一樣,這是個什么鬼?
別怕,名稱是一樣的,但是指向的修改是不一樣的,我們從.git/log/refs/stash 中可以看到 兩者的對應的節點指針是不一樣的
stash 的存儲的名稱是怎么來的,可以修改嗎?
當使用git stash 創建 stash 的時候,會給 stash 一個默認的名稱。之前有說,stash 存儲的內容就是,當前工作區距當前分支最后一次提交時的修改。所以,stash 的默認命名規則就是:
WIP on <branch_name> : <latest_commit_id> <latest_commit_message>WIP,Work In Progess的簡稱,說明代表了工作區進度。
同樣的還有 Index ,代表的是已經被 add 但是還未被提交的進度。
如果在未提交的情況下,執行 git stash 兩次,就如上圖,無法準確分辨兩個stash 具體修改的是哪些內容,這樣用,顯的偉大的 Git 一點都不智能,怎么可以!。
所以,在這種情況下,給 stash 存儲的修改起個名字,顯然非常重要,方式如下:
git stash save <message> $ git stash save "test-cmd-stash" Saved working directory and index state On autoswitch: test-cmd-stash HEAD 現在位于 296e8d4 remove unnecessary postion reset in onResume function $ git stash list stash@{0}: On autoswitch: test-cmd-stash從stash創建分支
如果你儲藏了一些工作,暫時不去理會,然后繼續在你儲藏工作的分支上工作,你在重新應用工作時可能會碰到一些問題。如果嘗試應用的變更是針對一個你那之后修改過的文件,你會碰到一個歸并沖突并且必須去化解它。如果你想用更方便的方法來重新檢驗你儲藏的變更,你可以運行 git stash branch,這會創建一個新的分支,檢出你儲藏工作時的所處的提交,重新應用你的工作,如果成功,將會丟棄儲藏。
$ git stash branch testchanges Switched to a new branch "testchanges" # On branch testchanges # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: index.html # # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # # modified: lib/simplegit.rb # Dropped refs/stash@{0} (f0dfc4d5dc332d1cee34a634182e168c4efc3359)注意
新增的文件,直接執行stash是不會被存儲的
如上圖:在git status 那一步很明顯可以看出來,我修改了README,添加了新文件abc.txt,然后執行了git stash save后,在執行git stash list 可以看到剛才的save是的信息,然后使用git stash show ,只顯示了README的改動被存起來了
執行了git statsh 以后,被存起來的在當前目錄再執行git status 就看不到了,但是我們現在再執行git status
這個文件還在,說明沒有被存起來。說白了就是沒有在git 版本控制中的文件,是不能被git stash 存起來的
那要怎么辦呢,這個文件我也想存起來,很明顯,先執行下git add 加到git版本控制中,然后再git stash就可以了
最后一步可以看出來,這個新增文件已經被stash了。
這個時候再執行下git status ,被存起來的在當前目錄就看不到了,如下:
這個時候,想切分支就再也不會報錯有改動未提交了。
如果要應用這些stash,直接使用git stash apply或者git stash pop就可以再次導出來了。
總結下:git add 只是把文件加到git 版本控制里,并不等于就被stash起來了,git add和git stash 沒有必然的關系,但是執行git stash 能正確存儲的前提是文件必須在git 版本控制中才行。
常規 git stash 的一個限制是它會一下暫存所有的文件。有時,只備份某些文件更為方便,讓另外一些與代碼庫保持一致。一個非常有用的技巧,用來備份部分文件:
1. add 那些你不想備份的文件(例如: git add file1.js, file2.js) 2. 調用 git stash –keep-index。只會備份那些沒有被add的文件。 3. 調用 git reset 取消已經add的文件的備份,繼續自己的工作。總結
以上是生活随笔為你收集整理的git 代码没了,git rebase 合并提交记录,git stash的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Swift调用摄像头之权限判断
- 下一篇: 简单编程---哥德巴赫猜想