我怎样才能重命名git藏匿?

时间:2014-09-19 09:46:32

标签: git git-stash

我的藏匿名称不正确。我想修改名称,以便它准确无误。

如何重命名存储?

10 个答案:

答案 0 :(得分:194)

让我们假设您的存储列表如下所示:

$ git stash list
stash@{0}: WIP on master: Add some very important feature 
stash@{1}: WIP on master: Fix some silly bug

首先,您必须删除要重命名的存储条目:

$ git stash drop stash@{1}
Dropped stash@{1} (af8fdeee49a03d1b4609f294635e7f0d622e03db)

现在,只需使用在删除后返回的提交sha的新消息添加它:

$ git stash store -m "Very descriptive message" af8fdeee49a03d1b4609f294635e7f0d622e03db

就是这样:

$ git stash list
stash@{0}: Very descriptive message
stash@{1}: WIP on master: Add some very important feature

此解决方案需要git 1.8.4或更高版本,是的,它也适用于脏工作目录。

答案 1 :(得分:59)

除非您手动执行或对Git做出改进,否则您可以使用别名:

git config --global alias.stash-rename '!_() { rev=$(git rev-parse $1) && git stash drop $1 || exit 1 ; git diff-index --quiet HEAD; s=$?; [ $s != 0 ] && git stash save "tmp stash from stash-rename"; git stash apply $rev && shift && git stash save "$@" && [ $s != 0 ] && git stash pop stash@{1}; }; _'

用法:“git stash-rename <stash> [save options] [<message>]

使用[save options] git stash save[-p|--patch] [-k|--[no-]keep-index] [-q|--quiet] [-u|--include-untracked] [-a|--all]

的任意选项$ git stash list stash@{0}: On master: Pep8 format stash@{1}: On master: co other than master with local changes stash@{2}: On master: tests with deployAtEnd # Let's say I want to rename the stash@{2} adding an issue reference: $ git stash-rename stash@{2} NXP-13971-deployAtEnd $ git stash list stash@{0}: On master: NXP-13971-deployAtEnd stash@{1}: On master: Pep8 format stash@{2}: On master: co other than master with local changes

示例:

git config --global alias.stash-rename '!_() { rev=$(git rev-parse $1) && git stash drop $1 || exit 1 ; git stash store -m "$2" $rev; }; _'

即使您有本地非分段更改,这也会有效:)

编辑2016/02/22

简化脚本,归功于 qzb https://stackoverflow.com/a/35549615/515973

git stash-rename <stash> [<message>]

用法:“{{1}}”

答案 2 :(得分:3)

我认为不可能这样做。有a proposal for stash renaming,但尚未实施。

  

我的总体想法是:

     
      
  1. 实现一个新的git reflog update命令,用于更新与特定reflog条目关联的消息。为此,新的update_reflog_ent()函数(在 reflog.c 中)将更改与要更新的特定reflog条目关联的消息。 update_reflog()函数会for_each_reflog_ent()使用update_reflog_ent来实际进行更改。

  2.   
  3. git stash rename命令只需要使用适当的ref和新消息调用git reflog update

  4.   

或者,当然,您可以弹出存储并执行git stash save [message]

答案 3 :(得分:3)

为了读者的利益,这里是extension to the currently accepted and correct answer

如果您不仅要更正存储消息并且还想更正存储的提交消息,那么

git stash list

git log --oneline -1 stash

既同意所​​展示的内容,又需要更多。可能有更好的方法,但我希望这里的食谱很容易理解。

为了能够git commit --amend,您需要处于分支机构的提示上。因此解决方案是:

git checkout -b scratch stash@{1}
git stash drop stash@{1}
git commit --amend -m "$MESSAGE"
git stash save -m "$MESSAGE" HEAD
git checkout master
git branch -D scratch

说明:

  • 创建一个新的(尚未存在的)&#34; scratch&#34;来自&#34;存储问题的分支&#34;并切换到它
  • 删除旧藏匿处。这是安全的,因为我们仍然在分支上。
  • 使用git commit --amend替换提交​​消息,这会更改&#34;存储的问题&#34;
  • 根据qzb's answer
  • 保存藏匿处
  • 切换回(假设您来自&#34; master&#34;)并清理

缺点:

  • 暂时切换分支。所以这个配方只能在git status --porcelain干净的时候应用(读:不输出任何东西)

  • 重新编号存储,因此更改的存储变为stash@{0}

  • 您需要输入$MESSAGE两次或使用一些环境变量(在示例中:MESSAGE

  • 您需要找到未使用的分支名称

有些方法可以在不切换分支的情况下执行此操作,但这超出了本答案的范围。

实施例

git init scratch
cd scratch
for a in A B C D; do date >$a; git add $a; git commit -m $a; done
for a in X Y; do echo $a > Z; git stash save --all; done
git log --oneline --graph --decorate --all; git stash list

输出

*-.   e0e281b (refs/stash) WIP on master: 8bdcc32 D
|\ \  
| | * 4d62f52 untracked files on master: 8bdcc32 D
| * 096f158 index on master: 8bdcc32 D
|/  
* 8bdcc32 (HEAD, master) D
* c84c659 C
* 49bb2da B
* b1852c6 A
stash@{0}: WIP on master: 8bdcc32 D
stash@{1}: WIP on master: 8bdcc32 D

现在没有改变提交(注意:以下的SHA在你身边会有所不同):

git stash drop stash@{1}
git stash store -m ...changed... 2fbf9007dfdfb95ae269a19e13b8b9ca3e24181c
git log --oneline --graph --decorate --all; git stash list

输出

*-.   2fbf900 (refs/stash) WIP on master: 8bdcc32 D
|\ \  
| | * 246dc5c untracked files on master: 8bdcc32 D
| * 80c5ea0 index on master: 8bdcc32 D
|/  
* 8bdcc32 (HEAD, master) D
* c84c659 C
* 49bb2da B
* b1852c6 A
stash@{0}: ...changed...
stash@{1}: WIP on master: 8bdcc32 D

如您所见,stash@{0}仍然在2fbf900 (refs/stash) WIP on master: 8bdcc32 D中显示为git log。如果你仔细观察,你会发现,有几个提交已经改变了SHA。这是由于如何处理藏匿处(父母被包含在SHA中,而且藏匿物作为父母存放)。

修正:

git checkout -b scratch stash
git stash drop
git commit --amend -m ...changed...
git stash store -m ...changed... HEAD
git checkout master
git branch -D scratch
git log --oneline --graph --decorate --all; git stash list

输出

*-.   4d55186 (refs/stash) ...changed...
|\ \  
| | * 246dc5c untracked files on master: 8bdcc32 D
| * 80c5ea0 index on master: 8bdcc32 D
|/  
* 8bdcc32 (HEAD, master) D
* c84c659 C
* 49bb2da B
* b1852c6 A
stash@{0}: ...changed...
stash@{1}: WIP on master: 8bdcc32 D

正如您所看到的,refs/stash也有一个更改的SHA。

答案 4 :(得分:2)

多年后回答我自己的问题:这是刚刚宣布的,所以我想我会在这里添加它。

许多 GUI git 客户端(例如 Fork 1.58 和更新版本)现在支持直接重命名存储。

enter image description here

答案 5 :(得分:1)

这很简单。首先,使用以下命令撤消最后一个存储区:

git stash pop

之后,您可以通过以下方式使用自定义名称保存存储空间:

git stash save "your explanatory name"

我希望它对您有用。 :)

答案 6 :(得分:0)

以下是Julien's alias的修改版本,可让您正确处理通常隐藏名称前面的On <branch>前缀:

git config --global alias.stash-rename '!_() { newmsg="$1" && stash=${2:-"stash@{0}"} && newbranch="$3" && sha=$(git rev-parse "$stash") && olddesc="$(git stash list --format=%gs -1 "$stash")" && newdesc="$(if [[ "$newbranch" = "." ]]; then echo "$newmsg"; else if [[ -n "$newbranch" ]]; then echo "On $newbranch: $newmsg"; else if [[ "$olddesc" =~ ":" ]]; then echo "$(echo "$olddesc" | cut -f1 -d":"): $newmsg"; else echo "$newmsg"; fi; fi; fi)" && git stash drop "$stash" > /dev/null || exit 1; git stash store -m "$newdesc" "$sha" && git stash list; }; _'

语法:

git stash-rename <new-name> [<stash> [<new-branch-name> | .]]

使用示例:

repo[master] % touch tmp && git add tmp && git stash save first
Saved working directory and index state On master: first
HEAD is now at bd62064 Initial commit
repo[master] % touch tmp && git add tmp && git stash save second
Saved working directory and index state On master: second
HEAD is now at bd62064 Initial commit
repo[master] % git stash list
stash@{0}: On master: second
stash@{1}: On master: first
repo[master] % git stash-rename renamed
stash@{0}: On master: renamed
stash@{1}: On master: first
repo[master] % git stash-rename also-renamed stash@{1}
stash@{0}: On master: also-renamed
stash@{1}: On master: renamed
repo[master] % git stash-rename branch-changed stash@{0} new-branch
stash@{0}: On new-branch: branch-changed
stash@{1}: On master: renamed
repo[master] % git stash-rename branch-name-persists
stash@{0}: On new-branch: branch-name-persists
stash@{1}: On master: renamed
repo[master] % git stash-rename no-branch stash@{0} .
stash@{0}: no-branch
stash@{1}: On master: renamed
repo[master] % git stash-rename renamed
stash@{0}: renamed
stash@{1}: On master: renamed
repo[master] % git stash-rename readd-branch stash@{0} develop
stash@{0}: On develop: readd-branch
stash@{1}: On master: renamed

大多数命令用于解析参数并确定应对分支名称执行的操作。使用的git工具如下:

  • git rev-parse <stash>找到藏匿的SHA。
  • git stash list --format=%gs -1 <stash>找到存储的 reflog主题。请注意,这与存储的提交消息不同,该命令不会更改。 reflog主题是git stash list中显示的内容,您可以更改reflog主题,而无需更改与stashes相关联的提交的哈希值。但是,您始终可以找到原始提交邮件,因此请勿使用git stash-rename删除敏感信息!
  • git stash drop <stash>将旧的引用放到存储中(但我们仍然拥有SHA,因此它不会丢失)。
  • git stash store -m <new-message> <sha>使用相同的提交信息将新的引用保存到存储中,但使用不同的 reflog主题
  • git stash list列出操作完成后的藏匿处。请注意,新的stashes总是被推到列表的开头。为了恢复原来的位置,有必要在感兴趣的藏匿处重新推送所有的藏匿处。

答案 7 :(得分:0)

最简单的方法:用git stash pop弹出你的藏品然后用git stash再次保存你的名字

答案 8 :(得分:0)

接受的答案中描述的方法仅在两个位置之一更新存储消息,导致许多 git 前端仍然显示旧消息。然而,可以创建一个提交来复制原始存储提交中的所有内容但更改其消息。

  1. 查找存储提交的树和父项的哈希值:

    $ git show -s --pretty=raw stash@{0}
    commit f2adfc7bbebe852693ad8f6ac889e4923230c872
    tree 8160d88c6e00e90fcfa183e09d2563f3cdfb304b
    parent a013bd8052d3260fbc95608ed69d0b9cfa0c77cb
    parent 5d5eb80dc03bea8ff2bdd38962a1259b7725d169
    author ...
    committer ...
    
        Test stash
    
  2. 使用相同的树和父级但不同的消息创建一个新提交:

    $ git commit-tree 8160d88c6e00e90fcfa183e09d2563f3cdfb304b \
      -p a013bd8052d3260fbc95608ed69d0b9cfa0c77cb \
      -p 5d5eb80dc03bea8ff2bdd38962a1259b7725d169 \
      -m "Renamed stash"
    f2adfc7bbebe852693ad8f6ac889e4923230c872
    
  3. 将此提交存储为新的存储

    $ git stash store \
      -m "$(git show -s --format=%B f2adfc7bbebe852693ad8f6ac889e4923230c872)" \
      f2adfc7bbebe852693ad8f6ac889e4923230c872
    

新的存储消息需要同时提供给 git-commit-treegit-stash-store 因为 git 将它存储在两个地方(提交和日志) /refs/stash)。

请注意,使用 --keep-index 创建的存储将有 3 个父级,因此在这种情况下,您需要向 git-commit-tree 提供第三个父级!

将此过程转换为单行代码以用于 git 别名作为练习留给读者;-)。请务必仅使用管道命令(因此避免使用例如 git-showgit-log)。

答案 9 :(得分:0)

这里有很多复杂的答案。我会这样处理:

首先让我们找到您的藏品索引:

git stash list

现在用 git stash apply {N} 应用它,例如

git stash apply 2

您现在可以使用新消息隐藏更改

git stash push -m 'My descriptive stash message'

如果您想清理原始存储,请记住将索引增加 1,因为新存储会增加所有现有索引(因此我们在这里使用 N + 1

git stash drop 3