从Git stash中查找并解压缩文件

时间:2012-12-03 09:19:21

标签: git

也许我经常使用git stash,但是当我想在项目中丢弃我的实验时,这就是我通常做的事情。

问题1:

  • 我如何在当前所有的藏匿处搜索文件名?

问题2:

  • 如何将此文件解压缩到单独的文件夹?

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

4 个答案:

答案 0 :(得分:10)

更重要的是要认识到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

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

E.g:

$ 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 

答案 1 :(得分:6)

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

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

我的答案的不同之处在于,虽然此处的其他答案会告诉您,您要查找的文件是否已更改,但是如果您想{{1},他们也不会告诉您该文件存在哪个藏匿处。那个藏匿。

我的回答纯粹是使用&#34;瓷器&#34; git命令,但它适用于我。

apply

所以回答问题1,我跑

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

给了我

> 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} 或进一步了解applystash{1}

答案 2 :(得分:3)

<强> TL;博士

grep stash for filename:

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

grep stash for content:

git stash list -G<regex>

搜索存储文件

的存储条目

来自git help stash

  

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

来自git help reflog

  

git reflog showgit log -g --abbrev-commit --pretty=oneline

的别名

来自git help log

  

<强> -g
  的 - 步行reflogs
  而不是走在提交祖先链上,将reflog条目从最新的条目转到较旧的条目。

git log synopsis

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

来自git revisions specifications

  

<refname>,例如master,heads / master,refs / heads / master
  一个象征性的引用名称。 ...
  如果不明确,则通过遵循以下规则中的第一个匹配来消除<refname>的歧义:

     
      
  1. 如果$GIT_DIR/<refname>存在,那就是您的意思(这通常仅适用于HEADFETCH_HEADORIG_HEADMERGE_HEADCHERRY_PICK_HEAD);

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

  4.   

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

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

因此我们stash将解析为refs/stash,而-g将导致整个分支被移动,并且` - &#39; fileglob &#39;将匹配该提交中的任何路径。

搜索存储内容

git help stash

  

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

来自git help log

  

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

所以简单的命令是:

git stash list -G<regex>

其他镐命令也应该有效。

答案 3 :(得分: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

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