ChatGPT解决这个技术问题 Extra ChatGPT

如何将本地未提交的更改合并到另一个 Git 分支?

如何在 Git 中执行以下操作?

我当前的分支是 branch1,我做了一些本地更改。但是,我现在意识到我实际上打算将这些更改应用于 branch2。有没有办法应用/合并这些更改,以便它们成为分支 2 上的本地更改,而无需在分支 1 上提交它们?

SO上有一个很棒的Git Tutorial here。它是所有关于堆栈溢出的 git 问题的中心。
由于 StackOverflow 的魔法,这个链接存在于右边的“链接”问题集中,但我认为它值得一个评论链接:另见 Move existing, uncommitted work to a new branch in Git

V
VonC

由于您的文件尚未在 branch1 中提交:

git stash
git checkout branch2
git stash pop

或者

git stash
git checkout branch2
git stash list       # to check the various stash made in different branch
git stash apply x    # to select the right one

以上是 rbentoanswer 的更长更明确的版本:

git stash
git stash branch branch2

它用:

git stash branch [] 从最初创建 的提交开始创建并签出一个名为 的新分支,将记录在 中的更改应用到新的工作树和指数。如果成功,并且 是 stash@{} 形式的引用,则它会删除 。如果您运行 git stash push 的分支发生了足够的变化,以至于 git stash apply 由于冲突而失败,这很有用。由于 stash 条目应用在 git stash 运行时为 HEAD 的提交之上,因此它恢复了最初的隐藏状态而没有冲突。

benjohnAs commented(参见 git stash man page):

要同时存储当前未跟踪(新添加的)文件,请添加参数 -u,因此:

git stash -u

不客气。 unethicalblogger.com/posts/2008/11/… 的更多存储使用示例。
如果您正在寻找使用 TFS 的相同问题的解决方案,等效的解决方案是搁置您的更改,然后使用 TFS Power Tools 使用 /migrate 开关取消搁置到正确的分支。
这对我有用。但是,我还必须为“stash pop”创建一个本地分支才能工作。如果您遇到类似情况,请查看 stackoverflow.com/questions/1783405/git-checkout-remote-branch
要同时存储当前未跟踪的(新添加的)文件,请添加参数 -u,即:git stash -u
@Benjohn 好点。我已将您的评论包含在答案中以提高知名度。
C
CB Bailey

存储、临时提交和变基可能都过大了。如果您尚未将更改的文件添加到索引中,那么您可以只签出另一个分支。

git checkout branch2

只要您正在编辑的文件在分支 1 和分支 2 之间没有不同,这将起作用。它会将您留在 branch2 上,并保留您的工作更改。如果它们不同,那么您可以指定要将本地更改与通过使用 -m 选项切换分支引入的更改合并到结帐。

git checkout -m branch2

如果您对索引添加了更改,那么您需要先通过重置来撤消这些更改。 (这将保留您的工作副本,它只会删除分阶段的更改。)

git reset

我认为存储“更简单”以某种方式理解,但您的方法更好地考虑跨不同分支的工作目录。 +1
简单的传统结帐似乎更适合手头的问题。 checkout 的重量更轻,它只是更新需要更改的文件。也许更容易理解 stash 方法,或者可能只是在这个用例中结帐是“安全”的还不够明显。
如果 checkout -m 在某些情况下不是“安全”的(可能会导致合并冲突),那么 stash 会提供任何优势(例如,您可以取消弹出 stash pop)吗?
@craigMcQueen您无法取消弹出弹出的存储,但是当您弹出时,存储会抱怨冲突。您可以修复冲突然后提交,但在这种情况下,原始存储仍然在堆栈上! :)
如果发生合并冲突,文件不是备份为 .orig 吗?
r
rbento

接受答案的更短的替代方法是:

暂时将更改移动到存储区。

混帐藏匿

创建并切换到一个新分支,然后只需一步将存储弹出到它。

git stash 分支 new_branch_name

然后只需 addcommit 对这个新分支的更改。


c
chakrit

警告:不适用于 git 新手。

这在我的工作流程中出现得足够多,以至于我几乎尝试为它编写一个新的 git 命令。通常的 git stash 流程是要走的路有点尴尬。我通常首先进行新的提交,因为如果我一直在查看更改,所有信息在我脑海中都是新鲜的,最好只是开始git commit - 我发现了什么(通常是一个错误修复属于我在功能分支上工作时发现的主人)。

如果您经常遇到这样的情况,在当前目录旁边有另一个工作目录也很有帮助,该目录始终签出主分支。

所以我如何实现这一点是这样的:

git 立即使用良好的提交消息提交更改。 git reset HEAD~1 撤消当前分支的提交。 (可选)继续开发该功能。

有时稍后(异步),或立即在另一个终端窗口中:

cd my-project-master 这是另一个 WD 共享相同的 .git git reflog 以查找我刚刚制作的错误修复。 git cherry-pick 提交的 SHA1。

可选地(仍然是异步的)然后您可以重新设置(或合并)您的功能分支以获取错误修复,通常当您即将提交 PR 并且已经清理了您的功能分支和 WD 时:

cd my-project 这是我正在研究的主要 WD。 git rebase master 以获取错误修复。

这样我就可以不间断地继续使用该功能,而不必担心git stash-ing任何事情或必须在git checkout之前清理我的WD(然后再次检查功能分支退出。)并且仍然拥有所有我的错误修正转到 master 而不是隐藏在我的功能分支中。

IMO git stashgit checkout 是真正的 PIA,当您正在开发一些重要功能时。


有趣且有效的替代我的答案。 +1
你是从mercurial来的吗? my-project-master 共享相同的 .git 听起来很像。为什么不是 git checkout -b bugfixABC; git commit -a; git reset HEAD^ --hard,然后在 mastergit cherry-pick <SHA1 of the commit(s) in bugfixABC 上稍后(异步)? (甚至,为了避免必须从您当前所在的任何分支中找出 SHA1 git rebase --onto master feature bugfixABC。这意味着您可以在上面的 git reset 之后直接在 feature 上执行此操作。)
但是,OP 听起来他们还没有准备好提交更改,在这种情况下,只有 checkout -m 更好。
c
claf

如果是关于提交的更改,您应该看看 git-rebase,但正如 VonC 在评论中指出的那样,当您谈论本地更改时,git-stash 肯定是做到这一点的好方法。


我不明白这个解决方案:它会从 branch1 重写 branch2 的提交历史......为什么当我们只想在 branch2 中获取 branch1 的本地未提交更改时,从 branch2 中获取所有已提交的更改?...
@VonC:同意,在这种情况下,rebase 会获取自上次分支之间合并到 branch1 以来所有已提交的更改。一开始我没有得到这个问题的“未提交”参数。 rebase 不是一个好的答案。
@claferri:pfew ......我开始头疼了;)我会否决你的答案,但由于我自己发表了一个,所以存在“明显的利益冲突”。有了你更新的帖子,我现在根本不需要投票。谢谢 :)
@VonC:下次,只要我的回答和这个一样错,请随意投反对票;)
S
Singh

这些是我遵循的步骤:

混帐克隆{链接}

cd {repo 文件夹}

您可以检查状态以及您正在使用的分支:

状态

git 分支

git 分支 -a

注意:如果您在移动到新分支之前在本地存储库中进行了更改,则以下步骤应该仍然有效。

如果“git branch”显示master,并且你想创建+移动到另一个分支:

git checkout -b {分支名称}

使用“git branch”再次检查分支它现在应该显示您在新分支中。

现在添加、提交和推送:

混帐添加。

git commit -m "添加新分支"

git push origin {分支名称}

上述步骤适用于我在移动到新的本地分支之前进行更改或在移动到新分支之后进行更改的情况。我希望它可以帮助遇到类似情况的人。


Y
Yves Boutellier

如果未提交的更改是未跟踪和已跟踪更改的混合

什么是未跟踪的更改?

当您创建例如一个新文件时。例如,VSCode 在文件资源管理器中的文件旁边显示一个 U

什么是跟踪更改?

当您对之前提交到 repo 的文件进行更改时(在以前的提交中)。

程序的快速说明

因此,假设您在分支 A 上,但您只想将现有文件的更改提交到分支 A,而新创建的文件(未跟踪)应该提交到新的分支 B。可以通过一些技巧来使用存储,逐步解释。

将脚本添加到 .git/config

.git 文件夹中有一个 config 文件。打开它,你会看到这样的东西:

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    ignorecase = true
    precomposeunicode = true
[remote "origin"]
    url = https://github.com/...
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
    remote = origin
    merge = refs/heads/main

将配置文件更改为:

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    ignorecase = true
    precomposeunicode = true
[alias]
    stash-untracked = "!f() {    \
                git stash;               \
                git stash -u;            \
                git stash pop stash@{1}; \
            }; f"
[remote "origin"]
    url = https://github.com/...
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
    remote = origin
    merge = refs/heads/main

现在,您可以在分支 A 上使用以下命令。

git stash-untracked

如果您使用的是 VSCode 之类的编辑器,您会看到新文件消失了(它现在被隐藏了)

仍在分支 A 阶段并将更改提交到现有文件:

git add .
git commit -m "committing tracked changes to current branch"

下一步是创建一个新的分支 B(使用 checkout -b 您可以立即访问它)

git checkout -b newBranchName

使用 stash pop 时,隐藏的更改会添加到您的当前分支。

git stash pop

唯一剩下的就是在新分支 B 上暂存并提交更改

git add .
git commit -m "created new file"