仅存储git中的阶段性变化 - 是否可能?

问题描述 投票:246回答:8

有没有办法可以隐藏我的分阶段变化?我遇到问题的情况是,我在给定时间处理了几个错误,并且有几个未分阶段的更改。我希望能够单独存档这些文件,创建我的.patch文件,并将它们存放起来,直到代码被批准为止。这样,当它被批准时,我可以存储我的整个(当前)会话,弹出该错误并推送代码。

我是以错误的方式来做这件事的吗?我是否误解了git如何以其他方式工作以简化我的流程?

git git-stash
8个回答
341
投票

是的,无论是否相信,它都是可能的:DOUBLE STASH:

  1. 存储您需要存储的所有文件。
  2. 运行git stash --keep-index。此命令将创建一个包含所有更改(暂存和未暂存)的存储,但会在工作目录中保留暂存的更改(仍处于暂存状态)。
  3. 运行git stash save "good stash"
  4. 现在你的"good stash"只有暂存文件。

现在,如果您在存储之前需要非暂存文件,只需应用第一个存储(使用--keep-index创建的存储),现在您可以删除存储到"good stash"的文件。

请享用


62
投票

使用最新的git,您可以使用--patch选项

git stash push --patch

并且git会要求您将文件中的每个更改添加或不添加到存储中。你只需回答yn


41
投票

我创建了一个脚本,只保存当前暂存的内容,并保留其他所有内容。当我开始做太多无关的更改时,这很棒。简单地发布与所需提交无关的内容并将其存储起来。

(感谢Bartłomiej的起点)

#!/bin/bash

#Stash everything temporarily.  Keep staged files, discard everything else after stashing.
git stash --keep-index

#Stash everything that remains (only the staged files should remain)  This is the stash we want to keep, so give it a name.
git stash save "$1"

#Apply the original stash to get us back to where we started.
git stash apply stash@{1}

#Create a temporary patch to reverse the originally staged changes and apply it
git stash show -p | git apply -R

#Delete the temporary stash
git stash drop stash@{1}

6
投票

为什么不为某个bug提交更改并从该提交及其前身创建补丁?

# hackhackhack, fix two unrelated bugs
git add -p                   # add hunks of first bug
git commit -m 'fix bug #123' # create commit #1
git add -p                   # add hunks of second bug
git commit -m 'fix bug #321' # create commit #2

然后,要创建适当的补丁,请使用git format-patch

git format-patch HEAD^^

这将创建两个文件:0001-fix-bug-123.patch0002-fix-bug-321.patch

或者,您可以为每个错误创建单独的分支,因此您可以单独合并或重新定义错误修复,如果它们无法解决,甚至可以删除它们。


4
投票

在这种情况下,我更喜欢为每个问题创建新的分支。我使用前缀temp /所以我知道我以后可以删除这些分支。

git checkout -b temp/bug1

分阶段修复bug1并提交它们的文件。

git checkout -b temp/bug2

然后,您可以根据需要从相应分支机构中提取提交并提交拉取请求。


1
投票

是否绝对有必要同时处理几个错误?而“一下子”,我的意思是“同时为多个错误编辑文件”。因为除非你绝对需要,否则我只会在你的环境中一次处理一个bug。这样你就可以使用本地分支和rebase,我发现这比管理复杂的存储/阶段要容易得多。

让我们说master在提交B.现在开始处理bug#1。

git checkout -b bug1

现在你在分支bug1上。进行一些更改,提交,等待代码审查。这是本地的,所以你不会影响其他任何人,它应该很容易从git diffs制作一个补丁。

A-B < master
   \
    C < bug1

现在你正在研究bug2。回到git checkout master掌握。建立一个新的分支,git checkout -b bug2。进行更改,提交,等待代码审查。

    D < bug2
   /
A-B < master
   \
    C < bug1

让我们假装其他人在你等待审查的时候对主人提交E&F。

    D < bug2
   /
A-B-E-F < master
   \
    C < bug1

当您的代码获得批准后,您可以使用以下步骤将其重新绑定为master:

git checkout bug1
git rebase master
git checkout master
git merge bug1

这将导致以下结果:

    D < bug2
   /
A-B-E-F-C' < master, bug1

然后你可以推送,删除你的本地bug1分支,然后离开你。在您的工作区中一次出现一个错误,但使用本地分支,您的存储库可以处理多个错误。这避免了复杂的舞台/藏匿舞蹈。

在评论中回答ctote的问题:

好吧,你可以回到每个bug的存储,并且一次只能处理一个bug。 Atleast可以为您节省分期问题。但经过尝试,我个人觉得很麻烦。在git日志图中,stashes有点乱。更重要的是,如果你搞砸了什么,你就无法恢复。如果你有一个脏的工作目录并且你弹出一个存储,你就不能“撤消”那个pop。搞砸现有的提交要困难得多。

所以git rebase -i

将一个分支重新绑定到另一个分支时,可以以交互方式(-i标志)进行。执行此操作时,您可以选择要对每个提交执行的操作。 Pro Git是一本很棒的书,也是HTML格式的在线书,有一个很好的关于变基和压缩的部分:

http://git-scm.com/book/ch6-4.html

为方便起见,我会逐字窃取他们的例子。假装您有以下提交历史记录,并且您希望将bug1重新绑定并压缩到master:

    F < bug2
   /
A-B-G-H < master
   \
    C-D-E < bug1

这是您在键入git rebase -i master bug1时将看到的内容

pick f7f3f6d changed my name a bit
pick 310154e updated README formatting and added blame
pick a5f4a0d added cat-file
#
# Commands:
#  p, pick = use commit
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

要将分支的所有提交压缩为单个提交,请将第一个提交保留为“pick”并用“squash”或简单地“s”替换所有后续“pick”条目。您也将有机会更改提交消息。

pick f7f3f6d changed my name a bit
s 310154e updated README formatting and added blame
s a5f4a0d added cat-file
#
# Commands:
#  p, pick = use commit
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit

所以,是的,挤压是一种痛苦,但我仍然会建议它大量使用藏匿处。


0
投票

在您对Mike Monkiewicz的评论中,我建议使用更简单的模型:使用常规开发分支,但使用合并的squash选项在主分支中获得单个提交:

git checkout -b bug1    # create the development branch
* hack hack hack *      # do some work
git commit
* hack hack hack *
git commit
* hack hack hack *
git commit
* hack hack hack *
git commit
git checkout master     # go back to the master branch
git merge --squash bug1 # merge the work back
git commit              # commit the merge (don't forget
                        #    to change the default commit message)
git branch -D bug1      # remove the development branch

此过程的优点是您可以使用正常的git工作流程。


0
投票

为了完成同样的事情......

  1. 暂存您要处理的文件。
  2. git commit -m 'temp'
  3. git add .
  4. git stash
  5. git reset HEAD~

繁荣。您不想要的文件被隐藏起来。你想要的文件都准备好了。

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