如何在我的分支中只存储多个已更改文件中的一个?
当前回答
VonC将文件复制到Git存储库外部的“中间”解决方案的问题是,您会丢失路径信息,这使得稍后将一堆文件复制回来有些麻烦。
A发现使用tar(类似的工具可能会这样做)而不是复制更容易:
tar cvf/tmp/stash.tar路径/to/some/file路径/to/some/other/file(…等)git签出路径/to/some/file-path/to/some/other/file暂存tar xvf/tmp/stash.tar等等(见VonC的“中间”建议)
其他回答
更新(2015年2月14日)-我重写了一点脚本,以更好地处理冲突的情况,现在应该将其显示为未合并的冲突,而不是.rej文件。
我经常发现,与@bukzor的方法相反更直观。也就是说,要进行一些更改,然后只隐藏那些已进行的更改。
不幸的是,git没有提供git存储——只有索引或类似的内容,所以我编写了一个脚本来实现这一点。
#!/bin/sh
# first, go to the root of the git repo
cd `git rev-parse --show-toplevel`
# create a commit with only the stuff in staging
INDEXTREE=`git write-tree`
INDEXCOMMIT=`echo "" | git commit-tree $INDEXTREE -p HEAD`
# create a child commit with the changes in the working tree
git add -A
WORKINGTREE=`git write-tree`
WORKINGCOMMIT=`echo "" | git commit-tree $WORKINGTREE -p $INDEXCOMMIT`
# get back to a clean state with no changes, staged or otherwise
git reset -q --hard
# Cherry-pick the index changes back to the index, and stash.
# This cherry-pick is guaranteed to succeed
git cherry-pick -n $INDEXCOMMIT
git stash
# Now cherry-pick the working tree changes. This cherry-pick may fail
# due to conflicts
git cherry-pick -n $WORKINGCOMMIT
CONFLICTS=`git ls-files -u`
if test -z "$CONFLICTS"; then
# If there are no conflicts, it's safe to reset, so that
# any previously unstaged changes remain unstaged
#
# However, if there are conflicts, then we don't want to reset the files
# and lose the merge/conflict info.
git reset -q
fi
您可以将上面的脚本保存为路径上的某个位置的git stash索引,然后将其作为git stach索引调用
# <hack hack hack>
git add <files that you want to stash>
git stash-index
现在,存储包含一个新条目,该条目仅包含您已暂存的更改,而您的工作树仍然包含任何未暂存的更改。
在某些情况下,工作树的更改可能取决于索引的更改,因此当您隐藏索引更改时,工作树更改会发生冲突。在这种情况下,您将得到通常的未合并冲突,可以使用gitmerge/gitmergetool/等解决。
将以下代码保存到一个文件中,例如,名为stash。用法是stash<filename_regex>。参数是文件完整路径的正则表达式。例如,要隐藏a/b/c.txt、隐藏a/b/c.txt或隐藏.*/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
}
}
}
您还可以选择只存储单个文件、文件集合或文件内的单个更改。如果您将-p选项(或--patch)传递给git stash,它将遍历工作副本中每个更改的“hunk”,并询问您是否希望隐藏它:
$ git stash -p
按以下键之一,它将运行该命令
Command Description
y stash this hunk
/ search for a hunk by regex .
? help .
n don't stash this hunk .
q quit (any hunks that have already been selected will be stashed) .
s split this hunk into smaller hunks
当您尝试在两个分支之间切换时,会出现这种情况。
尝试使用“git add filepath”添加文件。
稍后执行此行
git stash—保留索引
我已经回顾了这个问题的答案和评论以及一些类似的线索。请注意,为了能够隐藏任何特定的跟踪/未跟踪文件,以下命令都不正确:
git stash-p(--patch):手动选择大块,不包括未跟踪的文件git stash-k(--keep index):隐藏所有跟踪/未跟踪的文件,并将它们保存在工作目录中git stash-u(--包括未跟踪的):隐藏所有已跟踪/未跟踪的文件git stash-p(--patch)-u(--include untracked):无效命令
目前,能够隐藏任何特定跟踪/未跟踪文件的最合理方法是:
暂时提交不想隐藏的文件添加并隐藏弹出临时提交
在回答另一个问题时,我为这个过程编写了一个简单的脚本,这里有SourceTree中执行该过程的步骤。
推荐文章
- 如何将git配置存储为存储库的一部分?
- 如何修改GitHub拉请求?
- 如何在Github和本地删除最后n次提交?
- 我如何调试git/git-shell相关的问题?
- 错误:无法使用rebase进行拉取:您有未分阶段的更改
- Git隐藏未缓存:如何把所有未分期的变化?
- 真实的恶魔
- 如何从另一个分支获得更改
- Git:权限被拒绝(publickey)致命-无法从远程存储库读取。克隆Git存储库时
- git reflog和log有什么区别?
- git推挂在Total line之后
- 重命名git子模块
- 结合Git存储库的前两次提交?
- Xcode 6 gitignore文件应该包括什么?
- 我如何从现有回购的分支创建一个新的GitHub回购?