16

也许我使用 git stash 太频繁了,但是当我想扔掉我在项目中的实验时,我通常会这样做。

问题一:

  • 我如何在我当前的所有存储中搜索文件名?

问题2:

  • 如何将此文件提取到单独的文件夹中?

  • 或其他选项:如何为该隐藏文件启动视觉差异工具?

4

4 回答 4

15

更重要的是要认识到这refs/stash是一个伪分支(ref)的reflog:

git rev-list --walk-reflogs stash # (long option)
git rev-list -g stash # (short option)

所以你可以找到文件:

for sha in $(git rev-list -g stash); 
do 
     git ls-tree -r $sha:; 
done |
   grep "$SOMEFILENAME" | 
   sort --unique

(唯一的排序是删除不同存储中相同版本的重复项)。

例如:

$ for sha in $(git rev-list -g stash); do git ls-tree -r $sha:; done | grep numeric.js | sort -u
100644 blob f1c9a61910ae1bbd562615444a45688b93e9d808    LSPO.Web/DaVinci/JScript/numeric.js

因此,您可以使用例如启动视觉差异

kompare numeric.js <(git cat-file -p f1c9a61910ae1bbd562615444a45688b93e9d808)

当然,如果您已经预感到哪个 reflog 包含不同的文件,这会容易得多:

git diff stash@{3} -- numeric.js 
于 2012-12-03T22:26:03.150 回答
6

@sehe 的回答为问题 2 提供了很好的答案。

我来到这个页面是为了寻找比我目前使用的更好的问题 1 答案。我目前使用的是一个 shell 脚本stashshowall.sh,然后我 grep 输出。

我的答案的不同之处在于,虽然这里的其他答案会告诉您您要查找的文件是否已更改,但它们不会告诉您文件在哪个存储区,以防您想要存储该文件apply

我的回答纯粹是使用“瓷器”git 命令,但它对我有用。

#!/bin/sh
#  stashshowall.sh
for stash in `git stash list | sed 's/\(\w*\)\:.*/\1/'`
do
    echo
    echo "$stash"
    git stash show $stash
done

所以要回答问题 1,我运行

> stashshowall.sh | grep "stash\|some-file"

这给了我

stash@{0}
stash@{1}
 .../some-dir/some-file     | 16 ++--
stash@{2}
stash@{3}
stash@{4}
 .../some-dir/some-file     | 2 ++--
stash@{5}

这样我就知道我需要apply或进一步查看stash{1}stash{4}

于 2014-06-23T21:53:28.727 回答
6

tl;博士

grep stash 获取文件名:

git reflog stash -- '*fileglob*'
git log -g stash -- '*fileglob*'

grep stash 内容:

git stash list -G<regex>

搜索文件名的存储条目

git help stash

您创建的最新存储存储在refs/stash; 较旧的存储可在此参考的 reflog 中找到,并且可以使用通常的 reflog 语法命名(例如stash@{0}...)

git help reflog

git reflog show是一个别名git log -g --abbrev-commit --pretty=oneline

git 帮助日志

-g
--walk-reflogs
不是遍历提交祖先链,而是将 reflog 条目从最近的条目遍历到较旧的条目。

git日志简介

git log [<options>] [<revision range>] [[\--] <path>...]

git 修订规范

<refname>,例如 master、heads/master、refs/heads/master
一个符号 ref 名称。...
当模棱两可时, a<refname>通过采用以下规则中的第一个匹配来消除歧义:

  1. 如果$GIT_DIR/<refname>存在,这就是你的意思(这通常只对HEAD, FETCH_HEAD, ORIG_HEAD,MERGE_HEAD和有用CHERRY_PICK_HEAD);

  2. 否则,refs/<refname>如果存在;

现在我们把所有东西都放在一起了:

git reflog stash -- '*fileglob*'
git log -g stash -- '*fileglob*'

所以我们stash将解析为refs/stash,-g并将导致整个分支被遍历,并且 `-- ' fileglob ' 将匹配该提交中的任何路径。

搜索存储内容

git帮助藏匿

...该命令采用适用于git log命令的选项来控制显示的内容和方式。请参阅git-log

git 帮助日志

-G<regex>
查找补丁文本包含匹配的添加/删除行的差异<regex>

所以简单的命令是:

git stash list -G<regex>

其他镐命令也应该工作。

于 2017-05-24T02:03:20.200 回答
2

我用它在 stashes 中搜索文件

git stash list | cut -d ":" -f 1 | xargs -L1 git diff --stat | grep <filename>

您可以创建一个包含存储 ( git checkout -b <new_branch> <stash>) 的新分支,然后将文件复制到任何地方,然后将其合并回来。

您可以使用git difftool来查看您的差异。

编辑:要获得存储的提交以及文件名,您可以使用此 shell 脚本:

for i in $(git stash list | cut -d ":" -f 1 | xargs -L1 git show | grep commit |
  cut -d" " -f 2)
do
  if git show $i --oneline --stat | grep ht.h 
  then
    echo $i
  fi
done

它将在文件名下打印提交。

于 2012-12-03T15:27:31.453 回答