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

问题描述 投票:158回答:7

我有一个名字不正确的藏匿处。我想修改名称,以便准确。

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

git git-stash
7个回答
208
投票

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

$ 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或更高版本,是的,它也适用于脏工作目录。


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

即使您有本地未分阶段的更改,这将工作:)

编辑2016/02/22

简化的脚本,qzb,https://stackoverflow.com/a/35549615/515973的学分

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

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


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. 然后,git stash rename命令只需要使用适当的ref和新消息调用git reflog update

或者,你当然可以弹出藏匿处并做一个git stash save [message]


3
投票

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

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

git stash list

git log --oneline -1 stash

两者都同意所显示的内容,你需要更多。可能有更好的方法,但我希望这里的食谱很容易理解。

为了能够做git commit --amend你需要在分支机构的TIP上。因此解决方案是:

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

解释:

  • 从“存储问题”中创建一个新的(尚未存在的)“临时”分支并切换到它
  • 删除旧的藏匿处。这是安全的,因为我们仍然在分支上有这个。
  • 使用git commit --amend替换提交消息,这改变了“存储问题”的SHA
  • 根据qzb's answer存储存储
  • 切换回(假设你来自“主人”)和清理

缺点:

  • 这会临时切换分支。所以这个配方只能在git status --porcelain干净时应用(读:不输出任何东西)
  • 它重新整理了藏匿处,因此改变的藏匿处变成了stash@{0}
  • 您需要输入两次$MESSAGE或使用一些环境变量(在示例中:MESSAGE
  • 您需要找到未使用的分支名称

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

Example

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。


1
投票

这是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总是被推到列表的开头。为了恢复原来的位置,有必要在感兴趣的藏匿处重新推动所有的藏匿处。

1
投票

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

git stash pop

在此之后,你可以用这种方式用自定义名称保存存储:

git stash save "your explanatory name"

我希望它对你有用。 :)


0
投票

最简单的方法:使用git stash pop弹出你的存储,然后使用git stash保存你的名字再次保存它

© www.soinside.com 2019 - 2024. All rights reserved.