【问题标题】:connect a local repo to a new branch on a remote repo将本地仓库连接到远程仓库上的新分支
【发布时间】:2021-11-02 01:10:20
【问题描述】:

我有一个远程 GitLab 存储库 my-project,其中包含 2 个分支 masterdev。我在我的本地机器上有一个名为my-project 的目录,我正在其中开发一些代码,它的结构或多或少与远程仓库相同。我想做的是:

  1. 将目录初始化为 git repo(我已经这样做了)
  2. 以某种方式将初始化的本地存储库连接到远程存储库。
  3. 然后根据远程 repo 的master 分支的结构创建一个分支(不会丢失本地 repo 上的任何文件)。
  4. 最后,将本地仓库中的代码推送到新仓库中新建的分支。

到目前为止我所做的是:

cd my-project
git init
git fetch
git checkout -b new_dev_branch
git add .
git commit -m "first trial"
git remote add origin path/to/remote/gitlab/my-project.git
git push -u origin new_dev_branch

但问题是它没有像我在第 3 步中想要的那样创建具有 master 结构的分支。

有什么想法吗?

【问题讨论】:

    标签: git github gitlab


    【解决方案1】:

    TL;DR

    您已在新存储库中创建了一个新的 root 提交。那不是你想要的。您需要一个不同的(非根)提交。

    Sajib Khan's answer,建议merge或者cherry-picking,很可能会碰到绊脚石(取决于你具体的Git版本,但既然你提到了GitLab,那你的Git版本就会比2.9更新)。

    您可以通过多种方式解决此问题。阅读下面的“长”部分以了解所有这些内容,以及为什么这个摘要应该是正确的(请注意,我实际上无法测试它)。以下是“修复事物”命令序列的摘要,这是您从当前位置向前的最短路径:

    git push --delete origin new_dev_branch
    git branch -m error
    git fetch
    git switch -c new_dev_branch --no-track dev
    git restore --source error -SW -- .
    git commit
    

    (在这里输入一个好的提交信息!)

    git push -u origin new_dev_branch
    

    我假设您拥有 Git 2.23 或更高版本;如果没有,请参见下文。

    你是从错误的想法开始的。您认为 Git 存储文件,而分支名称与此有很大关系。但这些都不对! Git 存储库的核心是提交 的存储系统。换句话说,任何存储库中的存储单元都是提交。

    现在,commits 确实包含文件。但诀窍在于每个提交都包含 每个 文件——或者更准确地说,“它包含的每个文件”,尽管这听起来是多余的。您选择一个特定的提交,例如 a123456,并告诉 Git 签出该提交。 Git 删除其他文件,然后提取该提交中的文件。您现在拥有来自该提交的文件

    同样,这里真正的重点是,并且一直是提交。我们总是要关心commit。不过,对于我们人类来说,这里有一个问题:提交有这些看起来很可怕的随机 hexadecimal 数字,例如 a123456f1dd1ee 或其他任何东西,除了它们更大、更长、看起来更随机(我的-向上的,比如deadcabfeedc0ffee,至少类似 词)。我们把这些东西称为hash IDs,每个commit都有一个唯一的hash ID,也就是commit的“真名”。

    不过,人类无法正确处理哈希 ID,因此 Git 为我们提供了名称。我们以 分支名称 开头,例如 masterdev。这些名称让 Git 为我们记住 latest 哈希 ID。但这些名称实际上只是意味着让我获得最新的提交,其哈希 ID 存储在该名称中。还有其他种类的名称,但 branch 名称有一个特殊属性,我们很快就会看到。

    这对你意味着什么

    这对你意味着你不能仅仅创建一个新的 Git 存储库1你必须首先复制现有的存储库时间>。这样做的原因是,您在 Git 存储库中所做的每个新提交,都会连接回一些现有的提交。所以你必须首先get他们的提交,这样你就可以将你的新提交连接到他们旧的(现有的)提交。所以这个顺序不太行:

    1. 将目录初始化为 git repo(我已经这样做了)
    2. 以某种方式将初始化的本地存储库连接到远程存储库。
    3. 然后根据远程 repo 的 master 分支的结构创建一个分支(不丢失本地 repo 上的任何文件)。
    4. 最后,将本地仓库中的代码推送到新仓库中新建的分支。

    可以就地修复,但这很棘手。如果可以,重新开始会容易得多。我将首先介绍如何做到这一点。


    1嗯,你是被允许的,如果你这样做只会成为一个问题。


    重新开始,第 1 部分

    鉴于您有一个充满文件的目录(或文件夹),并且这些文件是您希望在新分支上的新提交中拥有的文件,我们首先将其放在一边。我们准备好了,但我们还没有使用它

    我们现在使用git clone 创建一个 文件夹(或目录)。这实际上是执行五个或六个单独命令的简写,我们将在“如何修复现有设置”部分中看到,但现在,请这样想:git clone 告诉你的 Git 软件在你的计算机在某处调用其他计算机,在他们的计算机上获取一些 Git 软件以导航到某个 Git 存储库,并让他们倾出他们所有的提交。您的 Git(您计算机上的软件)将所有提交复制到您计算机上的新存储库中。这些提交形成分支,其最新提交被记住 - 由他们计算机上的 Git 软件 - 带有分支名称。但是,当您的 Git(计算机上构建新存储库的软件)从他们的 Git(他们的软件读取他们的存储库)中获取所有信息时,您的 Git 不会复制任何他们的分支名称​​原样。您的 Git 使用它们的分支名称并更改它们。

    他们的 Git 存储库有一些 URL,例如 ssh://git@gitlab.com/path/to/repo.git2 你的 Git——我再次表示“你的软件在你的计算机上运行,​​在你的本地存储库上运行”——将存储这个名称下的 URL。 git clone 在此处使用的默认标准名字是 origin。我们将此名称称为 remote,因此该 URL 被存储为名为 origin 的远程。

    这会影响分支名称的变化。当您的 Git 从他们的 Git 克隆所有提交时,您的 Git 会采用他们的 branch 名称并将它们更改为 remote-tracking 名称。他们的master 变成你的origin/master;他们的dev 成为你的origin/dev。因此,在克隆过程的这一点上,您的每个 分支 名称都有一个 远程跟踪名称

    如果它们有三个分支名称,它们就有三个“最近提交”哈希 ID。您现在拥有三个远程跟踪名称,通过在每个分支名称前添加 origin/ 来创建。3

    现在您拥有他们的所有提交并且没有他们的分支git clone 执行最后一个特殊技巧:它创建一个分支并检查输出该分支的最新提交。它创建的分支取决于您提供给git clone-b 参数。如果您不给git clone -b,您的Git 会询问他们的Git 他们推荐哪个name。他们通常会推荐 master,或者 GitHub 现在以 main 开头,您的 Git 将根据您的 origin/masterorigin/main 创建该名称,您的 Git 使用他们的 master 或 @987654357 @。

    这个复杂的舞蹈的结果是你现在有 一个 分支,与它们的一个分支同名。您的 Git 现在使用 git checkoutgit switch4 来检查 该分支上存储在该分支名称中的最新提交(您的 Git 从远程复制- 从他们的分支名称跟踪名称)。


    2有时这是本地文件路径,在这种情况下,“他们的计算机”实际上就是您的计算机。有时这是一个网络驱动器,但如果是这样,您最终会发现使用这样的网络驱动器很容易出错:最好使用实际的网络协议并调用驱动器所在的另一台计算机是本地的。但这是一个单独的主题。

    3从技术上讲,远程跟踪名称与分支名称位于单独的namespace 中。这意味着即使您创建拼写为origin/something 的(本地)分支名称,它也不是远程跟踪名称。 Git 会让它们保持直截了当——默认情况下,git branch -a 将以红色显示远程跟踪名称,以其他颜色显示分支名称,这样你就会知道哪个是哪个——但不要不要那样做;它让人类变得疯狂。

    4git switch 命令是 Git 2.23 中的新命令。这是采用旧的git checkout 的结果,它有两种模式——一种“安全”和一种“不安全”——并将其拆分为两个单独的命令:git switch,它只实现安全模式的签出操作,和git restore,它实现了不安全模式的签出操作。如果你有 2.23 或更高版本,学习新命令是个好主意,这样当你认为你正在调用安全模式时,你就不会意外调用不安全模式,但它们实际上几乎相同。


    侧边栏:提交与工作树,以及索引的简要介绍

    是时候在这里使用一个简短的(嗯,简短的)侧边栏,关于存储在 Git 提交中的 已提交 文件,与您使用的文件。了解这一点将解释很多关于 Git 的其他方面的神秘之处。

    Git 提交中的所有内容都是只读的。 一旦您(或任何人)进行了提交,任何提交的任何部分都无法更改。这样,每次提交都会在该特定版本中永远存储每个文件,或者至少,只要具有该特定哈希 ID 的提交继续存在。 (remove 提交有点困难,我们不会在这里讨论。)

    提交中的文件不像普通文件那样存储在您的计算机上。相反,它们采用特殊的、只读的、仅限 Git 的、压缩的和去重格式。这处理了大多数提交主要重用来自先前提交的大多数文件的事实。 Git 实际上只存储文件的内容一次。当您更改内容时,Git 将不得不存储一个新副本,但如果您重新使用旧文件 - 甚至更改文件 back - Git 将能够重新使用较早的存储版本。

    但这意味着提交中的文件实际上只能 Git 本身读取,而 nothing 可以写入。换句话说,这些提交的文件不能用于日常工作。所以他们不是。相反,当您签出提交时,Git 会从提交中提取归档文件

    这个提取过程是git checkoutgit switch 的大部分内容。除了最初的git clone,我们从一些我们现在已经签出的提交开始。然后我们选择一个不同的提交来签出,并且:

    1. Git 删除当前提交的文件。
    2. Git 填充来自不同提交的文件,然后成为当前提交。

    这种删除和填充发生在您的工作树中,这只是您工作的区域。这些是您可以查看编辑的文件。但它们不在 Git 中。它们只是 从 Git 中提取的,来自提交。

    每当 Git 执行此提取步骤时,它都会在 Git 调用的不同地方跟踪这些文件,例如 index暂存区,或者——很少有这些天——缓存。这是同一事物的三个名称。这非常重要——例如,当你切换提交时,Git 会从这里获取要删除的文件列表——但我们根本不会在这里正确介绍它。请记住,当您运行git add 时,您正在创建或更新此索引/暂存区域中的文件副本。当您运行 git commit 时,Git 会根据该暂存区域中的文件制作新的提交快照

    因此,您在您的工作树工作,并从索引/暂存区域提交。但是,在您提交之前,您的文件不会 Git 中。5commits 是存储文件的存储单元。

    当你提交时,Git 会:

    • 打包它在其索引/暂存区域中的所有文件,包括来自当前提交的所有未修改的文件;
    • 添加提交元数据,例如您的姓名和电子邮件地址;
    • 使用当前提交哈希ID作为新提交的
    • 写出新的提交,永久保存打包的文件,或者只要这个新的提交继续存在;和
    • 最后,将新提交的哈希 ID(在写出提交期间获得)写入当前分支名称

    最后一步将新的提交添加到当前分支。 这是分支名称的特殊属性。 当我们添加新提交时,Git 会“向前移动分支名称”。新的提交链接回 之前的最终提交,而现在 new 提交 是最终提交。

    这意味着,如果我们提取提交,使用大写字母代表分支名称,我们会得到这样开始的图片:

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

    H 是在master 上的最后 提交,我们签出/提取。然后我们在我们的工作树中处理这个提交一段时间,并运行git addgit commit 来创建一个新的提交I,它将指向现有的提交H。然后 Git 会将 new 提交的 hash ID I 写入 name master:

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

    当我们有多个分支名称时,我们通常从两个指向同一个提交的名称开始,像这样:

    ...--G--H   <-- master (HEAD), new-branch
    

    然后我们运行git checkout new-branchgit switch new-branch 来选择正确的name:

    ...--G--H   <-- master, new-branch (HEAD)
    

    请注意,Git 巧妙地注意到我们正在从提交 H 移动到提交 H,这意味着我们并没有真正改变 提交。因此,Git 不会担心删除和替换任何文件。6 然后我们进行更改并添加和提交:

    ...--G--H   <-- master
             \
              I   <-- new-branch (HEAD)
    

    请注意新的提交I 仍然像以前一样指向提交H。但这一次,我们没有移动名称master。我们移动了名称new-branch

    这种从提交到提交的链接在 Git 中至关重要。没有它,Git 就无法工作。所以当我们进行新的提交时,我们必须从正确的开始提交开始。


    5由于 Git 的内部存储格式,git add 确实将文件的内容——而不是它的名称——放入了 Git。内容字节可以在特定事故或灾难后恢复一段时间。但是,如果您不提交它们,内容字节最终会被丢弃,除非它们与某些现有提交重复。

    6这个优化让我们创建并切换到一个新的分支名称​​在我们开始工作之后,以防我们忘记做提前那个。


    重新开始,第 2 部分:您将使用的命令

    1. git clone <em>url</em>:这会将 Git 存储库(或者更确切地说,它的提交)复制到您的计算机,并在新的结帐中为您提供一个新的工作树。然后cd(或任何你的change-working-directory命令)进入新的克隆。

    2. git checkout dev,如有必要(或将-b dev 添加到上面的克隆命令中)。请记住,您在此处通过分支名称选择期望的开始提交。如果您更喜欢新的 git switch,请运行 git switch dev(或者,再次在步骤 1 中的克隆命令期间使用 -b 选项)。

    3. git checkout -b new_dev_branch,创建 new 分支名称并切换到它。使用 git switch-b 更改为 -c(创建):git switch -c new_dev_branch-b-c 这里没有押韵或理由;你只需要记住它。

    4. 运行您的本地命令将每个文件您现在拥有它们的位置复制到此处的工作树。或者,考虑运行git rm -r .,从此处的工作树中删除所有文件,然后从其他位置复制所有文件。7

    5. git add .git add 用于每个新文件; git rm 用于您要删除的任何文件。这会更新 Git 的索引 AKA 暂存区,以便您准备好提交。

    6. git commit,进行新的提交并更新名称new_dev_branch

    7. git push origin new_dev_branch:这会让你的 Git 调用他们的 Git,使用存储在名称 origin 下的 URL。您的 Git 将您拥有的、他们没有的、他们需要的任何新提交交给他们的 Git:即您在步骤 6 中所做的提交。然后,给他们这个新提交(以及其中的任何全新文件-重复数据删除意味着您不必给他们任何仍然匹配的 old 文件),您的 Git 会要求他们的 Git 创建新的分支名称 new_dev_branch。由于这个名字对他们来说新的,所以你可以这样做,假设你被允许创建新名字。他们的名字 new_dev_branch 现在将记住与您的名字 new_dev_branch 记住的相同的“最后”提交,并且您的 Git 将创建 origin/new_dev_branch 以记住他们的 Git 将此提交记住为他们名为 new_dev_branch 的分支。

      这个命令目前可能会失败,所以你需要选择一个不同的分支名称,或者首先删除远程中的new_dev_branch名称,或者使用强制-push。请参阅下面有关从您目前所做的工作中恢复的部分。

    8. git branch --set-upstream-to origin/new_dev_branch:这让你的 Git 将现有分支 new_dev_branchupstream 设置设置为你的 origin/new_dev_branch,这是你的 Git 对其分支名称 new_dev_branch 的记忆.

    您只需执行第 8 步一次:您的 Git 存储库中的每个分支名称都可以准确地记住一个上游。记住上游是可选的,但可以为您提供一些不错的功能。

    您可以进行第 7 步,git push 操作,使用git push -u origin new_dev_branch 为您执行第 8 步。这只是一个方便的捷径。当且仅当 git push 部分成功时,它将运行第 8 步。由于您只需要在希望它更改时设置上游,因此您只需要一次-u 选项。


    7如果您使用某种整体文件移动操作,请注意:Git 存储库 本身存储在.git 目录(或文件夹)中在你的工作树的顶部。这是 Git 保存所有自己的文件的地方,也是实际存储库所在的地方。你的工作树是你的,你可以用它做任何你想做的事,只要你记住一些 Git 命令,比如git restoregit reset --hard,会在你的工作树上乱涂乱画文件。但是Git的仓库文件对Git来说很宝贵,如果弄错了,Git会伤心8停止工作。

    8不要将计算机拟人化,他们讨厌那样!


    你已经运行了git init,但它并没有达到你想要的效果。以下是如何恢复。

    从你的问题来看,这是你跑的。我已经对它们进行了编号,以便我们可以在下面引用它们。

    1. cd my-project
    2. git init
    3. git fetch
    4. git checkout -b new_dev_branch
    5. git add .
    6. git commit -m "first trial"
    7. git remote add origin path/to/remote/gitlab/my-project.git
    8. git push -u origin new_dev_branch

    第 1 步非常简单。在第 2 步中,Git 告诉你:

    Initialized empty Git repository in .../my-project/.git/
    

    如果它说它重新初始化一个现有 Git 存储库,请停在这里!这仅适用于 new repository 的情况。

    第 3 步只会默默地什么都不做,因为 没有可从中获取的遥控器。所以你仍然有一个空的存储库:

    $ git init
    Initialized empty Git repository in ...
    $ git fetch
    $
    

    我不确定为什么 Git 不在这里抱怨;确实应该。

    Git 存储库没有提交,也没有分支。虽然它没有分支,但你仍然某个分支上:你只是在一个不存在的分支上。这是一种特殊的情况,但 Git 在您创建第一次提交时会修复它。因此,我们继续进行第 4 步,这会将您所在的分支的名称(不存在)从 master 更改为 new_dev_branch

    $ git checkout -b new_dev_branch
    Switched to a new branch 'new_dev_branch'
    

    步骤 5 将当前目录中的所有文件添加到 Git 的 index/staging-area 中,以便它们可以提交。只要它有效,它就不会产生任何输出。然后第 6 步将所有这些文件以及添加的元数据转换为这个新存储库中的 first 提交。存储库不再是空的,所以现在分支名称可以存在。分支名称出现,指向这个提交。这个提交不能指向任何更早的提交,所以它没有。 Git 将此称为 root 提交:

    $ git add .
    $ git commit -m "first trial"
    [new_dev_branch (root-commit) f342d15] first trial
     1 file changed, 1 insertion(+)
     create mode 100644 README
    

    就我而言,我只有一个文件,README,我添加了。注意(root-commit);这里的号码f342d15 是唯一的,所以你的号码会有所不同;当前分支名称为new_dev_branch,该分支现在已存在。

    您的步骤 7创建了一个名为 origin 的远程,存储 URL (path/to/remote/gitlab/my-project.git)。这使git push 命令能够运行。您的第 8 步发送了您的新 root 提交并创建了一个名为 new_dev_branch 的分支。由于您的根提交没有 parent 提交,因此它不会链接到现有提交的历史记录。

    鉴于您真的不希望其他 Git 存储库将此提交用作 new_dev_branch,您可能应该首先从位于 origin 的存储库中删除 new_dev_branch: p>

    git push --delete origin new_dev_branch
    

    这会让你的 Git 调用他们的 Git 并要求他们删除名为 new_dev_branch 的分支。

    让我们也将(本地)分支重命名为 error,这样我们就可以将其排除在外:

    $ git branch -m error
    $ git branch
    * error
    

    接下来,我们需要从另一个 Git 存储库中获取他们的所有提交。这很容易做到:现在就运行git fetch!我还没有设置另一个存储库,所以我不会在这里显示任何输出:

    git fetch
    

    你的 Git 会调用他们的 Git,让他们列出他们所有的分支名称和相应的提交哈希 ID,并使用这些 ID 从他们的 Git 中获取所有他们的提交,并在您自己的本地存储库,每个分支名称的远程跟踪名称。完成后,运行 git branch -agit branch -r 以查看所有这些名称。

    (注意:没有明显的原因,git branch -r 将远程跟踪名称列为origin/masterorigin/dev 等,但git branch -a 将它们列为remotes/origin/masterremotes/origin/dev 等开。这与我之前提到的命名空间有关。不过,git branch -a 仍然没有理由这样做。)

    我们现在要检查一些现有的提交,这些提交是通过一些远程跟踪名称找到的。这将从您的工作树中删除您已提交到根提交中的所有文件,该文件位于当前名为 error 的分支上。没关系,因为它们都安全地存储在 commit 中。

    请注意,我们没有名为 dev 的分支,也没有名为 master 的分支。然而,我们可以运行:

    git checkout dev      # or git switch dev
    

    或与master 相同。这会调用 Git 所称的 DWIM 模式,或者——在最新版本的 git checkoutgit switch 中——--guess 模式。此模式默认启用;使用--no-guess 将其关闭。

    这个模式做什么很简单:如果没有我们给的名字的branch,在说出error: no such branch: dev之类的东西之前,Git会四处寻找我们的远程跟踪名称。如果有一个足够类似我们要求的名称,Git 将表现得好像我们在运行:

    git checkout -b dev origin/dev
    

    或:

    git switch -c dev origin/dev
    

    也就是说,Git 将创建我们的dev,基于我们的origin/dev,它基于origindev。这与git clone 在初始克隆过程中使用的技巧相同:如果他们dev,我们可能希望我们的 dev 匹配。这就是猜测,或“按我的意思做”:DWIM。

    你可以明确地运行:

    git checkout -t origin/dev
    

    或:

    git switch -t origin/dev
    

    -t--track 选项(允许拼写)表示这是远程跟踪名称;根据该名称创建一个分支,并设置新分支的上游。上游设置发生在 DWIM / --guess 代码也执行其操作时,因此 -t 只是一个显式变体。9

    现在我们有了一个dev,并且它的文件已经被检出——我假设你希望你的new_dev_branchthis 提交开始——现在我们已经准备好从分支error上的根提交中的所有文件进行提交。这里的事情有点棘手。

    我们现在需要做的是:

    • 将工作树中的所有文件替换为来自error 的文件;
    • 将Git索引中的所有文件替换为error中的文件;和
    • 提交。

    有一种简单直接的方法可以做到这一点:

    git rm -r .
    git checkout error -- .
    git commit
    

    首先从 Git 的索引和我们的工作树中删除所有文件。如果 当前提交 中有一些文件不会出现在 new 提交中,我们只有 必须 这样做。

    然后我们使用git checkout 的“危险”模式清除所有文件。在这一点上这并不是很危险,因为已经这样做了。我们用分支error 命名的提交中的文件替换这些文件。 -- . 告诉git checkout指定提交中的所有文件,就像git rm -r . 告诉 Git索引中的所有文件

    有两种方法可以避免git rm -r 步骤。其中一个非常神奇,因为它使用了 Git 的 管道命令之一。我们只需运行:

    git read-tree -m -u error
    

    我不太喜欢这个,因为它太魔幻了。相反,我们可以使用:

    git restore -s error -SW -- .
    

    这更明确:我们要求git restore 将所有文件恢复到它们在提交error 中的样子,删除该提交中不是的所有文件。这与git checkout error -- . 不同,后者不会删除 不在该提交中的文件。10-SW 选项告诉 Git 同时写入索引和工作树。

    使用git restoregit read-tree,或两个命令删除和替换git rmgit checkout 序列来修复我们的索引和工作树,我们现在只需运行git commit。像往常一样,这会在当前分支上进行新的提交。 in 这个新提交中的文件与分支 error 上的 (lone, root) 提交中的文件完全匹配。

    我们现在可以在git push -u origin new_dev_branch 上(重新)创建new_dev_branch 分支origin。它包含此提交所有早期提交,因此它是所需的历史记录。

    我们可以使用最后一个技巧来缩短它。我们跑了:

    git checkout dev
    

    origin/dev 创建dev,然后:

    git checkout -b new_dev_branch
    

    使用相同的提交哈希 ID 创建new_dev_branch,并切换到new_dev_branch,没有为new_dev_branch 设置上游。但是我们可以组合这些,代价是首先不创建本地dev 分支——这是一个微不足道的成本,因为我们总是可以稍后创建它。我们需要做的就是:

    • 创建new_dev_branch,指向正确的提交
    • 但没有设置上游

    为此,我们可以使用:

    git checkout -b new_dev_branch --no-track origin/dev
    

    --no-track 阻止 Git 将 origin/dev 设置为上游。实际上 设置 这几乎是无害的(我们将用git push -u 替换它),但避免它可能更好更安全。当然,如果你有git restore,你也有git switch,我们可能应该使用它,所以我们想要:

    git switch -c new_dev_branch --no-track origin/dev
    

    这里,作为我们的捷径。


    9如此多的方法大多是历史偶然。但是,如果您有 两个或更多 个遥控器,所有遥控器都有一个dev,就会出现一些问题。假设你有r1/devr2/dev,你运行git checkout dev,而你没有dev。 Git 应该使用哪个远程跟踪名称,r1/devr2/dev?使用git checkout -t r2/dev 告诉Git 使用哪一个,所以-t 选项在DWIM 模式不可用时有效。

    10在内部,Git 称之为--overlay--no-overlay。在旧版本的 Git 中,git checkout 始终以 --overlay 模式运行,git restore 始终以 --no-overlay 模式运行。在现代 Git 中,这些选项是公开的。详情请参阅the documentation


    更多关于git clone

    如果不将git clone 扩展到其组成部分,这将是不完整的。您可以使用六个命令复制git clone 所做的事情,其中​​一个是纯 shell(或 CLI)命令,其余 Git 命令在新目录中运行:

    1. mkdir <em>clone</em> &amp;&amp; cd <em>clone</em>,或您的 CLI 等效项:创建新目录。
    2. git init:在这里创建一个空的 Git 仓库。
    3. git remote add origin <em>url</em>:添加一个名为origin 的远程来存储给定的 URL。如果您提供了 -o 选项,请使用其他名称。
    4. 您需要的任何git config 命令,如果您将-c 选项提供给git clone,或类似--single-branch 的选项(但如果您愿意,您可以将单分支放在git remote add 中) .
    5. git fetchgit fetch <em>remote</em>(如果不是 origin,我不确定您是否必须拼出远程名称,但您可以)。
    6. git checkout <em>branch</em>:使用-b 或推荐的分支创建您选择的分支(学习推荐很棘手,但在大多数情况下您可以假设mainmaster)。如果您使用了-n,请跳过此步骤。

    运行git clone 只是做了这六个步骤,有点花哨:它发现了推荐的分支名称;如果您不将其指向某个现有的空目录,它会根据 URL 计算出要创建的目录的名称;如果出现问题,它将删除部分构建的克隆。但这实际上只是隐藏了它为您运行git fetchgit checkout 的事实。

    【讨论】:

    • 非常感谢@torek 的详细而有帮助的回复。我担心我使用的方法将来会造成伤害。另外,我在新推送的分支文件夹中发现了一个名为 my-project.git 的文件夹,还有一些其他文件,如 head 等。我想了解更多关于 Git 和版本控制的信息。如果您能向我推荐一些有用的资源,我将不胜感激。我知道是否也应该练习,但最好在使用命令之外建立一个扎实的理解。
    • 目前我只推荐一本关于 Git 的 ,那就是免费的 Pro Git 2 书。我认为可能有一本更好的书,但其他书在这一点上大多已经过时了;这个更新了。一旦您习惯了一些 Git 基础知识,我还建议您通读 Think Like (a) Git
    【解决方案2】:

    您可以将远程master 分支拉入您的new_dev_branch 分支:

    $ git checkout new_dev_branch
    $ git pull origin master
    

    现在,检查是否一切正常,然后推送到远程:

    $ git push origin new_dev_branch
    

    您可以执行以下操作的另一种方式 -

    签出到new_dev_branch 分支并复制最新的提交哈希:

    $ git checkout new_dev_branch
    $ git log
    # copy the latest commit_hash
    

    remote's master 分支创建一个新分支(例如new_dev_branch_2)。现在,接受(樱桃采摘)你的承诺:

    $ git checkout -b new_dev_branch_2 origin/master
    $ git cherry-pick <commit_hash> 
    

    现在,检查是否一切正常,然后将new_dev_branch_2 分支推送到远程。

    $ git push origin new_dev_branch_2
    

    【讨论】:

      猜你喜欢
      • 2021-04-07
      • 2012-06-26
      • 2012-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-05
      • 2021-11-14
      相关资源
      最近更新 更多