如何将主分支中的文件推送到另一个分支?

3

我刚开始使用git,所以需要将文件从主分支推送到另一个分支以备份以防万一,然后继续在主分支上工作。我该如何在git bash中完成这个操作?


2
从主分支,您可以使用git checkout -b new-branch检出到新分支,以便主分支中的代码将在新分支中存在。现在再次检出到您的主分支并继续编辑。 - siva
2
可能是重复的问题,参考如何将一个git分支中的单个文件版本复制到另一个分支中? - Pavel Anikhouski
@siva,就像这样。git checkout -b new-branch然后推到那个新分支,接着checkout -b old-branch? - mrmar
1
@Marko在第二个命令中不需要使用-b,因为它是创建分支的选项(而且该分支已经存在)。但在我看来,创建标签比创建分支更有意义。 - Philippe
@Philippe 我收到错误信息:“致命错误:当前备份分支没有上游分支。” - mrmar
2个回答

7
Git不会推送文件;Git只推送提交。提交包含文件,因此效果类似,但重要的是要记住:仓库要么有一个提交(然后有每个文件的快照),要么没有该提交(然后它就没有这些快照)。
为了将您在master上拥有的提交推送到其他Git存储库 - 您称之为origin的存储库 - 但让另一个存储库以除(它的)master之外的名称知道它们,您可以执行以下操作:
git push origin master:some-new-branch-name

这会将你拥有但他们需要的提交推送给origin上的Git。然后,它会向他们发送一条礼貌的请求:请设置名为some-new-branch-name的分支以记住我称之为master的提交。

(你的Git会向他们发送此提交的原始哈希值,而不是名称master。如果您愿意,可以使用以下命令查看该原始哈希值:

git rev-parse master

尽管查看一些哈希 ID 后,你很快就会明白人们为什么不经常使用它们 (除非你复制粘贴,否则很难正确输入)。

完成上述操作后,如果运行以下命令:

git fetch origin

您将看到现在有一个新的远程跟踪名称origin/some-new-branch-name。这是您的Git对其——origin的Git的分支名称some-new-branch-name的副本。如果运行以下命令:

git log --all --decorate --oneline --graph

你会注意到不仅有了新的分支名,而且它把与你自己的master相同的提交标识出来。

所有这一切都有点愚蠢和/或过度,除非你担心自己的代码库可能会被破坏。原因是一旦提交,它们就是永久性的-嗯,绝大部分情况是永久性的,并且只读(完全只读:任何提交中的内容都不能更改!)。提交本身实际上是通过哈希 ID 找到的。像master这样的分支名称只是作为起点:你的 Git 把你的名称master转换成一个又大又丑的哈希 ID,然后使用它来找到最后一次提交。那个最后一次提交有它之前或提交的大又丑的哈希 ID,所以从最后一次提交,你的 Git 可以往回走一步。父提交存储另一个父哈希 ID,这样从父提交,你的 Git 就可以往回移动另一步。那个提交又有另一个父 ID:

... <-F <-G <-H ...

给定任何提交哈希 ID,例如提交 H 的哈希 ID,Git 可以读取该提交并获取其父 ID。然后它可以读取 G 并获取另一个父 ID,然后再使用它来读取 F,以此类推。这就是分支的含义:它只是由哈希 ID 倒序串联而成的一系列提交,并且有一个分支名称指向系列中的最后一个提交。如果 H 是最后一个提交,则系列如下所示:

...--F--G--H   <-- master

名字 master 可让您的Git找到提交记录H。这使得您的Git可以找到G,然后是F等等。

当您向master添加新的提交时,Git实际上正在编写一个新提交(带有一些新的随机外观的哈希ID),其父项是提交H。然后Git将新提交的哈希ID(我们称之为I)写入名称为master的位置,现在您就拥有了:

...--F--G--H--I   <-- master

当你创建一个新的 名称,例如 some-new-branch-name,Git 会创建一个指向某个现有提交的名称。默认情况下,新名称的提交是 当前 提交:

...--F--G--H--I   <-- master, some-new-branch-name

这也解释了Git的HEAD的含义。如果你有多个分支名称,当你做出新的提交时,Git如何知道要更新哪个名称呢?答案是:Git将特殊名称HEAD附加到一个分支名称上。这就是在你做出新的提交时需要更新的名称。因此我们真正应该画出这样的图:

...--F--G--H--I   <-- master (HEAD), some-new-branch-name

或者:

...--F--G--H--I   <-- master, some-new-branch-name (HEAD)

根据使用 git checkout 选择的分支名称,当前的提交是(真正的哈希ID)I;当前的分支名称是任何 HEAD 所指向的名称。

如果你担心文件,只需使用git checkout -b创建一个新的分支名称,并在需要的情况下进行提交(或者首先进行提交,如果您希望将更改添加到另一个分支,请先进行提交,如果这更为适合)。 您以前的分支名称现在记住了它的最后一次提交的哈希ID,而您的新分支名称则记住了您进行的任何提交的哈希ID:

...--F--G--H--I   <-- master
               \
                J--K   <-- some-new-branch-name (HEAD)

(一旦您有了两个仅在新分支上的提交)。

(请注意,提交I通过两个分支。)


这是一个很好的答案 - 你知道如何永久设置默认的远程主分支(master)(对于git push --all),因为“push -u”不行: git push -u "origin" "master:RELEASE12345" #不能永久设置 如果需要手动编辑.git/config文件,我也可以接受。 - Malcolm Boekhoff
这有点混乱。Git 有一种方法可以告诉它将推送到 branch@{upstream} 设置 - 请注意,git push -u ... 实际上是在告诉 Git 运行 git branch --set-upstream-to(如果推送成功)- 使用 push.default 设置为 upstream,但此默认设置仅适用于某些情况。请参阅(非常长的)git config 文档;搜索 push.default - torek

2

首先,您需要为这些备份创建一个新分支(但我认为没有必要,因为您也可以在主分支上回到任何提交,但好吧)。

本地创建新分支

要创建新分支,只需使用:

git branch <NAME OF NEW BRANCH>

最初的回答,或者在这种情况下,我们可以使用:

git branch backup

最初的回答是,之后我们需要切换到那个分支。
git checkout <NAME OF NEW BRANCH>

最初的回答
在这种情况下,我们将使用

git checkout backup

"最初的回答"翻译成英文是 "Original Answer"。
接下来,我们需要提交更改。
若要添加所有新文件(句点表示将替换所有当前未添加到提交的文件),请执行以下操作。
git add . 

And to do a commit

git commit -m "adding a backup branch"

最初的回答是:然后我们转到主分支。
git checkout master

"最初的回答" 可以翻译成 "原始答案"。关于内容的翻译是:"然后只需将这些更改推送到git存储库即可。"
git push origin <feature_branch>

最初的回答。
在这种情况下,
git push origin backup

将新文件从主分支推送到备份分支

如果您想在备份分支中以新文件为基础,可以使用以下命令:

git rebase master

这将会更新备份分支中的基础提交。你可以在这里阅读更多关于rebase的内容:https://git-scm.com/book/de/v2/Git-Branching-Rebasing。最初的回答。

git checkout -b 'branch_name' 会同时创建不存在的分支。 - OldFart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接