如何在我的分支中只存储多个已更改文件中的一个?
当前回答
使用SourceTree,这可以通过3个步骤轻松完成。
暂时提交所有你不想隐藏的东西。Git添加所有其他内容,然后将其隐藏。通过运行git reset来弹出临时提交,在临时提交之前进行提交。
这一切都可以在SourceTree中在几秒钟内完成,您只需单击要添加的文件(甚至单个行)。添加后,只需将它们提交到临时提交。接下来,单击复选框以添加所有更改,然后单击“隐藏”以隐藏所有更改。在隐藏的更改不碍事的情况下,浏览一下提交列表,并在临时提交之前记录提交的哈希值,然后运行“git reset hash_b4_temp_commit”,这基本上就像通过将分支重置为提交之前的提交来“弹出”提交。现在,只剩下不想隐藏的内容。
其他回答
我也想做同样的事情,但当我再次思考时,我意识到我不想为了保存一个文件而麻烦重重。对我来说,把它复制到其他地方并添加一些注释来提醒我为什么要把它保存在那里会容易得多。
不要误解我的意思:有很多原因可以解释为什么你只想隐藏一个文件,而且总的来说,使用版本控制软件总是最好的做法。但还是要确保你没有浪费时间。在我的情况下,我只想保留一个文件并放弃所有其他更改,然后在切换到新分支后将其弹出。所以cp/mv足够好。
将以下代码保存到一个文件中,例如,名为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
}
}
}
类似的情况。做了承诺,意识到这不好。
git commit -a -m "message"
git log -p
根据这些回答,这对我有帮助。
# revert to previous state, keeping the files changed
git reset HEAD~
#make sure it's ok
git diff
git status
#revert the file we don't want to be within the commit
git checkout specs/nagios/nagios.spec
#make sure it's ok
git status
git diff
#now go ahead with commit
git commit -a -m "same|new message"
#eventually push tu remote
git push
更新(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/等解决。
有时,我在提交分支之前对其进行了不相关的更改,我想将其移动到另一个分支并单独提交(如master)。我这样做:
git stash
git checkout master
git stash pop
git add <files that you want to commit>
git commit -m 'Minor feature'
git stash
git checkout topic1
git stash pop
...<resume work>...
请注意,第一个stash和stash pop可以取消,您可以在结账时将所有更改转移到主分支,但前提是没有冲突。此外,如果您要为部分更改创建新分支,则需要隐藏。
假设没有冲突和新分支,您可以简化它:
git checkout master
git add <files that you want to commit>
git commit -m 'Minor feature'
git checkout topic1
...<resume work>...
甚至不需要Stash。。。
推荐文章
- 强制LF eol在git的回购和工作副本
- Git:在裸库中更改活动分支的正确方法?
- 删除git中的分支是否会将其从历史记录中删除?
- 防止在GitHub上推送到master ?
- 根据Git,谁是“我们”,谁是“他们”?
- git如何合并后樱桃采摘工作?
- Git搜索单个文件历史记录中的字符串
- Git命令显示所有(轻量级)标签创建日期
- Gitignore并没有忽视文件夹
- 什么时候用。git/info/exclude代替。gitignore来排除文件?
- 如何告诉git忽略个别行,即gitignore为特定行代码
- “git diff——耐心”是什么意思?
- 我如何在GitHub中为其他人的代码做出贡献?
- 签出旧的提交并使其成为新的提交
- gitignore是什么?