将文件和更改从一个分支移动到另一个分支

Moving files and changes from one branch to another branch

我是 git 的新手。但是目前,我在 master 下有两个分支:

refactorfinal。我正在尝试将所有文​​件从 refactor 移动并推送到 final 但是,在签出到 refactor 并重新定位到 final 之后,我得到了最终错误:

fatal: Needed a single revision
invalid upstream final

基本上,我正在尝试在 refactor 中处理我的代码,并在测试后将其推送到 master。

我该怎么做?

从头开始倒推——顺便说一下,Git 也是这样做的——让我们看看这个:

invalid upstream final

这表明您 运行 git rebase final,但还没有 b运行ch 名称 final.

I am trying to move and push all files from refactor to final

这里有几件重要的事情需要了解,首先是:Git 并不是关于 文件 。我们稍后会回到那个,现在完成倒退:

But currently, I have two branches under master ...

B运行ches——更准确地说,b运行ch names——没有任何类型的 over/under 关系。 (这个 going-backwards 有点痛苦,不是吗?但这就是 Git 所做的,所以做一会儿是很好的练习。)

现在,关于 Git 需要了解的是,它是关于 提交 的。这与文件或 b运行ches 无关。文件和 b运行ches 当然很重要,但就 Git 而言,重要的是提交。一个提交 包含 个文件,我们发现一个提交 使用 一个 b运行ch 名称。但是 Git 就是关于提交的。那么,您可能想做的是移动提交,但这也可能是一个问题。这是你需要知道的。

Git 都是关于提交的

因为 Git 是关于提交的,所以您需要确切地知道提交是什么以及为您做什么。所以你必须记住一些东西:

  • 每个提交都有编号。他们不是在数数字,比如 1、2、3;但是每个提交都有一个唯一的编号。数字 看起来 运行dom,又大又丑,里面也有字母:例如 385c171a018f2747b329bcfa6be8eda1709e5abd。这些数字实际上是提交中所有内容的加密校验和。 Git 通过这个数字查找提交。

  • 每个提交都有两部分,数据元数据:

    • 提交中的数据只是 Git 您(或任何人)提交时知道的每个文件的快照。这些文件以特殊的 read-only、Git-only、压缩和 de-duplicated 形式存储。 de-duplication 处理这样一个事实,即大多数提交大多只是 re-use 上一次提交的所有文件。

    • 提交中的元数据包含诸如您的姓名和电子邮件地址之类的内容,以及您要放入的任何日志消息。Git 将自己的内容添加到此元数据中,但是:每个commit 存储 commit-number——哈希 ID——previous commit。 Git 将其称为提交的 父级

Git 中的大部分内容都不符合这些事实:

  • Git 不存储 更改 ,而是存储快照。

  • 提交串在一起,在 backwards-looking 链中:

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

    此处H是链中最后次提交的哈希ID。如果我们知道提交 H 的实际哈希 ID,我们可以让 Git 查找它。这会同时获取快照和其父提交的实际哈希 ID G。我们可以让 Git 查找它,它会得到一个较早的快照,以及 even-earlier 提交的哈希 ID F,等等。

  • 因为提交的 编号 是加密校验和,所以实际上不可能更改有关提交的任何内容。如果你取出一个并对其进行一些更改并存储结果,你会得到一个 新的和不同的 提交,具有不同的哈希 ID。旧的提交仍然存在,没有改变。

  • A b运行ch name 仅包含链中 last 提交的哈希 ID。

  • 当您进行新提交时,Git 将 new 提交的 ID 写入名称:

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

    在这里,我们添加了一个新的提交 Imaster。现有的提交没有改变:H 仍然指向 G,它仍然指向 F,等等。我们所做的只是添加一个新的提交 I 指向 H。当我们这样做时,因为我们使用的是 master,Git 将 I 的 ID 写入 name master.

所以 names 移动了,但是提交根本没有改变。

现在我们准备好查看“移动提交”

当你使用Git的时候,一般都是从git开始checkout <em>b运行ch</em>.这会将文件从一次提交中复制出来——记住,b运行ch 名称指定一次提交,并且提交中的文件采用 read-only、Git-only 形式——到你可以使用它们。它还告诉 Git name 是您当前的 name,因此特定的 commit 是您当前的 提交 。就是这些图:

...--G--H   <-- master (HEAD)

都是关于。特殊名称 HEAD 附加到 一个 b运行ch 名称,如 master。那是你当前的 b运行ch,以及对这一点是您当前的提交。

如果您现在创建一个新的 b运行ch 名称,例如 refactor,您会得到:

...--G--H   <-- master (HEAD), refactor

切换到名称 refactor 后,您会看到:

...--G--H   <-- master, refactor (HEAD)

无论如何,您仍在使用提交 H。只是提交 Hnamemasterrefactor.

现在您以通常的方式进行新的提交。如果您在 refactor 上执行此操作,则会发生以下情况:

...--G--H   <-- master
         \
          I--J   <-- refactor (HEAD)

在这里,您已经进行了两次新提交。这些快照,J 最后一个 ,包含文件和元数据。 J 指向 II 指向 H名称 refactor 选择提交 J 名称 master 选择提交 H.

I [would] like to commit all changes from repository refactor to repository final

等一下:你刚刚说了repository,但是之前你说了b运行ch.

A repository 是提交的集合(带有 b运行ch 名称,可以帮助您和 Git find 提交)。 A b运行ch 是......好吧,它是模棱两可的:人们用这个词来表示不同的东西。但是 b运行ch 名称 是一个可以帮助您和 Git 找到一个特定提交的名称,Git 根据需要从中反向工作。

如果你想要一个新的 b运行ch name 拼写 final 来标识提交 J,这很简单:

git branch final            # makes `final` point to the current commit

或:

git branch final refactor   # makes `final` point to the same commit as `refactor`

最终结果可能如下所示——请再次注意,实际上没有任何提交 更改:

...--G--H   <-- master
         \
          I--J   <-- refactor (HEAD), final

Git 用词非常混乱

Git有一堆专业术语,比如remoterepositoryb运行ch,依此类推。实际上并不是每个人都以正确的方式使用这些术语(其中一些一开始就不是很好,还有一些随着时间的推移而演变)。如果您试图将问题传达给人类,或让 Git 做某事,使用正确的术语可能非常重要,或者在您不确定时添加一些解释关于术语。

Git 有一个 glossary 可以帮助解决这个问题。它绝对不完美,但至少是一个起点。