stash用法 - stash git




只存儲使用Git更改過的多個文件中的一個文件? (18)

快速回答

要在git中還原特定的已更改文件,您可以執行以下操作:

git checkout <branch-name> -- <file-path>

這是一個實際的例子:

git checkout master -- battery_monitoring/msg_passing.py

如何在我的分支上只隱藏多個已更改文件中的一個?


地方變化:

  • file_A(已修改)未上演
  • file_B(已修改)未上演
  • file_C(已修改)未上演

要僅使用file_C上的更改創建存儲“my_stash”:

1. git add file_C
2. git stash save --keep-index temp_stash
3. git stash save my_stash
4. git stash pop [email protected]#{1}

完成。

說明

  1. file_C添加到暫存區域
  2. 創建一個名為“temp_stash”的臨時存儲,並將更改保存在file_C上
  3. 僅使用file_C上的更改創建想要的存儲(“my_stash”)
  4. 將“temp_stash”(file_A和file_B)中的更改應用於本地代碼並刪除存儲

您可以在步驟之間使用git status來查看正在進行的操作。


警告

正如評論中所指出的,這會將所有內容都放入存儲中,無論是分階段還是非分階段。 -step-index只在保存完成後單獨留下索引。 以後彈出存儲時,這可能會導致合併衝突。

這將隱藏您之前未添加的所有內容。 只需git add你想要保留的東西,然後運行它。

git stash --keep-index

例如,如果要將舊提交拆分為多個變更集,則可以使用此過程:

  1. git rebase -i <last good commit>
  2. 將某些更改標記為edit
  3. git reset HEAD^
  4. git add <files you want to keep in this change>
  5. git stash --keep-index
  6. 根據需要修復問題。 不要忘記git add任何更改。
  7. git commit
  8. git stash pop
  9. 必要時,從#5開始重複。
  10. git rebase --continue

一個複雜的方法是首先提交一切:

git add -u
git commit // creates commit with sha-1 A

重置回原始提交,但從新提交中檢出the_one_file:

git reset --hard HEAD^
git checkout A path/to/the_one_file

現在你可以存儲the_one_file:

git stash

通過在重置回原始提交時將已提交內容保存在文件系統中進行清理:

git reset --hard A
git reset --soft HEAD^

是的,有點尷尬......


你也可以使用git stash save -p "my commit message" 。 通過這種方式,您可以選擇將哪些帥哥添加到藏匿處,也可以選擇整個文件。

每個塊都會提示您一些操作:

   y - stash this hunk
   n - do not stash this hunk
   q - quit; do not stash this hunk or any of the remaining ones
   a - stash this hunk and all later hunks in the file
   d - do not stash this hunk or any of the later hunks in the file
   g - select a hunk to go to
   / - search for a hunk matching the given regex
   j - leave this hunk undecided, see next undecided hunk
   J - leave this hunk undecided, see next hunk
   k - leave this hunk undecided, see previous undecided hunk
   K - leave this hunk undecided, see previous hunk
   s - split the current hunk into smaller hunks
   e - manually edit the current hunk
   ? - print help

使用git stash push ,如下所示:

git stash push [--] [<pathspec>...]

例如:

git stash push -- my/file.sh

這是自2017年春季發布的Git 2.13開始提供的。


假設你有3個文件

a.rb
b.rb
c.rb

並且你想只存儲b.rb和c.rb而不是a.rb

你可以做這樣的事情

# commit the files temporarily you don't want to stash
git add a.rb
git commit -m "temp" 

# then stash the other files
git stash save "stash message"

# then undo the previous temp commit
git reset --soft HEAD^
git reset

你完成了! HTH。


另一種方法:

# Save everything
git stash 

# Re-apply everything, but keep the stash
git stash apply

git checkout <"files you don't want in your stash">

# Save only the things you wanted saved
git stash

# Re-apply the original state and drop it from your stash
git stash apply [email protected]{1}
git stash drop [email protected]{1}

git checkout <"files you put in your stash">

在我(再一次)來到這個頁面之後我想出了這個並且不喜歡前兩個答案(第一個答案就是沒有回答這個問題而且我不喜歡使用-p交互模式) 。

這個想法與@VonC建議使用存儲庫外部文件的想法相同,您可以保存您想要的更改,刪除存儲中不需要的更改,然後重新應用您移動的更改。 但是,我使用git stash作為“某處”(結果,最後還有一個額外的步驟:刪除你放在藏匿處的cahnges,因為你也將它們移開了)。


將以下代碼保存到文件中,例如,名為stash 。 用法是stash <filename_regex> 。 參數是文件完整路徑的正則表達式。 例如,要存儲a / b / c.txt, stash a/b/c.txtstash .*/c.txt等。

$ chmod +x stash
$ stash .*.xml
$ stash xyz.xml

要復製到文件中的代碼:

#! /usr/bin/expect --
log_user 0
set filename_regexp [lindex $argv 0]

spawn git stash -p

for {} 1 {} {
  expect {
    -re "diff --git a/($filename_regexp) " {
      set filename $expect_out(1,string)
    }
    "diff --git a/" {
      set filename ""
    }
    "Stash this hunk " {
      if {$filename == ""} {
        send "n\n"
      } else {
        send "a\n"
        send_user "$filename\n"
      }
    }
    "Stash deletion " {
      send "n\n"
    }
    eof {
      exit
    }
  }
}

我不知道如何在命令行上執行此操作,僅使用SourceTree。 假設您已經更改了文件A,並且在文件B中有兩個更改塊。如果您只想隱藏文件B中的第二個塊並保持其他所有內容不變,請執行以下操作:

  1. 一切都好
  2. 對工作副本執行更改以撤消文件A中的所有更改。(例如,啟動外部差異工具並使文件匹配。)
  3. 使文件B看起來好像只對其應用了第二個更改。 (例如,啟動外部差異工具並撤消第一次更改。)
  4. 使用“保持暫存更改”創建存儲。
  5. 一切都取消
  6. 完成!

我會使用git stash save --patch 。 我沒有發現交互性令人討厭,因為在它期間有選項將所需操作應用於整個文件。


我發現沒有答案是我需要的,這很簡單:

git add -A
git reset HEAD fileThatYouWantToStash
git commit -m "committing all but one file"
git stash

這只存儲了一個文件。


有時候,在我提交之前,我已經在我的分支上做了一個無關的更改,我想將它移動到另一個分支並單獨提交(如master)。 我這樣做:

git stash
git checkout master
git stash pop
git add <files that you want to commit>
git commit -m 'Minor feature'
git stash
git checkout topic1
git stash pop
...<resume work>...

請注意,可以消除第一個stashstash pop ,您可以在結帳時將所有更改傳遞到master分支,但僅限於沒有衝突。 此外,如果要為部分更改創建新分支,則需要存儲。

假設沒有衝突且沒有新分支,您可以簡化它:

git checkout master
git add <files that you want to commit>
git commit -m 'Minor feature'
git checkout topic1
...<resume work>...

藏匿甚至不需要......


由於git基本上是關於管理所有存儲庫內容和索引(而不是一個或多個文件),因此git stash交易毫不奇怪, 與所有工作目錄

實際上,自Git 2.13(2017年第2季度)以來,您可以使用git stash push存儲單個文件:

git stash push [--] [<pathspec>...]

pathspec被賦予' git stash push '時,新的stash僅記錄與pathspec匹配的文件的修改狀態

有關更多信息,請參閱“存儲對特定文件的更改 ”。

測試用例不言自明:

test_expect_success 'stash with multiple pathspec arguments' '
    >foo &&
    >bar &&
    >extra &&
    git add foo bar extra &&

    git stash push -- foo bar &&   

    test_path_is_missing bar &&
    test_path_is_missing foo &&
    test_path_is_file extra &&

    git stash pop &&
    test_path_is_file foo &&
    test_path_is_file bar &&
    test_path_is_file extra

原始答案(下面,2010年6月)是關於手動選擇您想藏匿的內容。

Casebash評論:

這個( stash --patch原始解決方案)很不錯,但我經常修改了很多文件所以使用補丁很煩人

的answer (upvoted,2011年11月)提出了一個更實際的解決方案,基於
git add + git stash --keep-index
去看看並提出他的答案,這應該是官方的(而不是我的)。

關於該選項, chhh在評論中指出了另一種工作流程:

你應該在這樣的藏匿之後“ git reset --soft ”來恢復你的明確階段:
為了達到原始狀態 - 這是一個明確的暫存區域,並且只有一些選擇的非階段性修改,可以輕輕地重置索引以獲取(不提交像你這樣的東西 - bukzor - 確實)。

(原始答案2010年6月:手動藏匿)

然而, git stash save --patch可以讓你實現你所追求的部分git stash save --patch

使用--patch ,您可以交互式地從HEAD和工作樹之間的差異中選擇要存儲的數據。
構建存儲條目,使其索引狀態與存儲庫的索引狀態相同,並且其工作樹僅包含您以交互方式選擇的更改。 然後,從您的工作樹中回滾所選更改。

但是,這將保存完整索引(可能不是您想要的,因為它可能包括已編入索引的其他文件),以及部分工作樹(可能看起來像您要隱藏的那個)。

git stash --patch --no-keep-index

可能更適合。

如果--patch不起作用,手動過程可能會:

對於一個或多個文件,中間解決方案是:

  • 將它們複製到Git倉庫之外
    (實際上, eleotlecram提出了一個有趣的選擇 )
  • git stash
  • 把它們複製回去
  • git stash #這次,只有你想要的文件被藏起來了
  • git stash pop [email protected]{1} #重新應用所有文件修改
  • git checkout -- afile #在任何本地修改之前將文件重置為HEAD內容

在相當繁瑣的過程結束時,您將只有一個或幾個文件被藏起來。


git stash -p (或git add -p with stash --keep-index )太麻煩時,我發現使用diffcheckoutapply更容易:

僅“隱藏”特定文件/目錄:

git diff path/to/dir > stashed.diff
git checkout path/to/dir

然後是

git apply stashed.diff

當您嘗試在兩個分支之間切換時,會出現這種情況。

嘗試使用“ git add filepath ”添加文件。

稍後執行此行

git stash --keep-index


這裡的每個答案都是如此復雜......

這個“藏匿”怎麼樣:

git diff /dir/to/file/file_to_stash > /tmp/stash.patch
git checkout -- /dir/to/file/file_to_stash

這將彈出文件更改回:

git apply /tmp/stash.patch

與存儲一個文件並將其彈回的完全相同的行為。


類似的情況。 提交並意識到它不行。

git commit -a -m "message"
git log -p

根據答案,這對我有所幫助。

# revert to previous state, keeping the files changed
git reset HEAD~
#make sure it's ok
git diff
git status
#revert the file we don't want to be within the commit
git checkout specs/nagios/nagios.spec
#make sure it's ok
git status
git diff
#now go ahead with commit
git commit -a -m "same|new message"
#eventually push tu remote
git push




git-stash