【问题标题】:git checkingout a branch then make that branch to head/mastergit 签出一个分支,然后将该分支设置为 head/master
【发布时间】:2018-06-15 00:23:15
【问题描述】:

假设我进行了最近的提交并将其推送到我的私有存储库,您如何返回要签出的分支,然后将其推送到存储库的头/主控??

git checkout branch_name

我必须执行什么命令才能将该 branch_name 移动到 master/head ?

【问题讨论】:

  • 我怀疑您在这里混淆了一些术语,因为在 Git 中,名称 HEAD 始终是当前提交。无论您签出什么,那都是HEADgit checkout masterHEAD 现在是主人; git checkout otherbranch; HEAD 现在是另一个分支; git checkout 1234567HEAD 现在已分离并提交 1234567。分支名称本身就是指向特定提交 ID 的可移动指针,它们通常会在您进行新提交时自动移动。
  • @torek 哦.. 好的,所以我检查了 my_branch,我添加了更改并提交它,每当我执行 git push origin master 时,它都会说所有内容都是最新的.. 我是怎么做到的每当我从另一台远程计算机上拉取它时,我所做的更改就会拉取?

标签: git


【解决方案1】:

提交并推送您的本地更改后。使用

git 获取

git 拉

git checkout {目标分支名称}

与主人合并

git 合并原点/master

【讨论】:

    【解决方案2】:

    HEAD 应该在你的master 分支中,然后你必须写:

    git merge branch_name
    

    要返回历史记录,您应该拥有要返回的提交的哈希值,然后:

    git checkout commit_hash
    

    Herehere 您可以查看文档以获取更多信息。

    【讨论】:

      【解决方案3】:

      让我们看看我是否理解正确。
      如果你想回到以前的提交,你有这个答案,它详细解释了该怎么做。

      How to move HEAD back to a previous location? (Detached head)

      如果您只想结帐分支,您可以这样做:

      # checkout the desired branch
      git checkout <branch>
      

      如果您希望查看所有分支并结帐其中一个:

      # Update the repository with the list of all branches and deleted the 
      # one who were deleted on the remote
      git fetch --all --prune
      
      # List all branches in the repository
      git branch -a
      

      How to work on several branches simultaneously?

      您使用git worktree 命令同时在多个分支上工作。

      来自 git v2.5

      git worktree add <new_path>
      

      git worktree 将创建 2 个相互独立的工作文件夹,同时指向同一个存储库。

      这将允许您对 enw 工作树上的任何实验进行操作,而不会对存储库本身产生任何影响。

      这是一个关于如何创建新工作树及其结果的示例:

      【讨论】:

        【解决方案4】:

        基于此评论:

        好的,所以我检查了 my_branch,我添加了更改并提交它,每当我执行 git push origin master 时,它都会显示所有内容都是最新的。当我从另一台远程计算机上提取它时,我该如何做到这一点,我所做的更改拉动?

        确实,您需要的是一个好的教程,但不幸的是,有很多不好的教程,而好的教程却不多。我推荐the Pro Git book。不过,要阅读和消化的内容很多。

        目前,让我们回顾一下您目前所掌握的内容,并就他们所做的事情做一些简短的(我希望)说明。让我们首先注意这里至少涉及两个存储库,一个是你的——你的克隆,是你用git clone 创建的——另一个是你在其他机器上以origin 的名字访问的。您所做的几乎所有事情都发生在您的克隆中,除了git push(打包来自您的克隆的提交,将它们传送到远程,并要求远程更改其分支名称之一以指向它们),以及一些git fetch(我们稍后会谈到)。

        到目前为止你做了什么

        第一:

        git checkout my_branch
        

        这告诉 Git 查找名称 my_branch,我们可以在这里假设它是您存储库中的现有分支。

        假设这成功了,Git 将HEAD 设置为指向my_branch。名称my_branch 指向某个特定的提交,所以从图表上看,我们有:

        ...(some commits)<-o<-o   <-- HEAD->my_branch
        

        os 代表提交。每个提交都指向它的 parent 提交,my_branch 指向最顶端(最右边)的此类提交。然后,Git 可以通过从 HEAD 开始查找所有提交,看到它指向 my_branch,查看 my_branch 指向的位置(提示提交),然后将每个提交跟踪到其父级。

        接下来,您添加/修改一些文件,可能删除一两个文件,并最终提交:

        ...
        git add ...
        ...
        git commit
        

        这使得 new 提交。通过像往常一样读取HEAD,发现它指向my_branch,读取my_branch 以找到它的提交(分支的当前提示),进行新提交的过程,以及然后从索引/暂存区域中的任何内容(您在上面git add-ed 的内容)中进行新的提交。作为最后一步,git 调整 my_branch 以指向 new 提交。

        让我们再次绘制该图,其中包含新的提交。让我们将新提交绘制为* 而不仅仅是o,这样我们就可以很容易地看到它是哪一个:

        ...(some commits)<-o<-o<-*   <-- HEAD->my_branch
        

        到目前为止一切顺利,但所有这些都严格保存在您自己的存储库中,所以现在我们来回答您关于 git push 的问题。在这里,事情变得有点复杂。

        你运行了这个:

        git push origin master
        

        但我们刚刚说过并在上面画了HEAD 指向my_branchmy_branch 指向这个新的* 提交。 master 在哪里?

        好吧,我们之前没有绘制它,而且我没有你的存储库,所以我不得不猜测。但让我猜猜master 指向o曾经是my_branch 的尖端。为了画这个,我不能再画箭头了(它们不在我在 StackOverflow 上的字符集中),所以我将使用\

        ...(some commits)<-o<-o     <-- master
                               \
                                *   <-- HEAD->my_branch
        

        这与之前的绘图相同,除了 (1) 我必须使用两条线和 (2) 我添加了 master 分支。

        当您运行 git push origin master 时,您要求您的 Git 调用 origin 的 Git 并向其发送一些提交,即您在 master 上拥有而在 master 上没有的任何提交.但是你和他们在master 上的提交相同,所以你的 git 说“一切都是最新的”并停止。

        您在这里拥有的是对 my_branch 的新提交。

        (另外,在你的新提交之前的提交是在 both my_branch master,至少在我刚刚制作的绘图中。我没有有你的存储库,所以我只是猜测。但几乎可以肯定 some 提交在两个分支上。与其他版本控制系统相比,这对于 Git 来说是不寻常的。稍后很重要,并且需要记住的一点:提交可以在许多个分支上。现在,这只是一个奇怪的问题。)

        你还能做什么:第 1 部分

        那么,你可以做些什么来让你的新提交到origin?您可以做的一件事是以my_branch 的名义推送它。如果origin 没有名为my_branch 的分支,则会在那里创建它。如果origin确实有一个my_branch,这将尝试设置他们的my_branch指向你的新提交*——当然,首先交付该提交。无论哪种方式:

        git push origin my_branch:my_branch
        

        或:

        git push origin -u my_branch:my_branch
        

        将尝试该请求。他们的 Git 可以接受或拒绝请求,并且通常会根据他们是否有一个名为 my_branch 的分支来这样做(如果有,它现在指向的位置)。

        注意my_branch:my_branch 中的重复。冒号 : 字符左侧的名称是 your 存储库中的分支名称,右侧的名称是您要询问的名称——远程上名为 origin 的 Git -设置。这两个名字不必相同!如果它们相同,您通常可以只写一次,这就是我们在git push origin master 中看到的。您也可以使用my_branch 来执行此操作。我喜欢包含冒号和目标名称,至少对于新用户来说是这样,因为我认为这会使正在发生的事情更加明显。

        您还可以做什么:第 2 部分

        您还可以做任何其他事情:

        • 使您的新提交出现在您的master 上(根据您的存储库现在的外观,采用几种方式之一);或
        • 复制您的新提交到您添加到 master 的另一个甚至更新的提交;或
        • 请他们 (origin) 接受您在 my_branch 上的新提交并将其添加到他们的 master

        最后一个相当于做第一个,然后做git push origin master

        如何将my_branch 上的新提交提交到(您的)master

        有两种方法可以做到这一点,它们可以做非常不同的事情。

        1. git merge:这有两个主要的子模式。它可以进行真正的合并,也可以进行 Git 所说的快进,这实际上根本不是合并。

        2. git reset:这有很多子模式,而且是一个非常锋利的工具,如果使用不当会引起很多悲伤。我们将在这里讨论的模式(但不是实际使用)是要注意它所做的在某种程度上就像git push 要求遥控器做的最后一步。它告诉 Git 从它现在指向的任何提交上剥离一个分支标签,而是让它指向某个 other 提交。

        我们先看git reset,具体来说就是“剥离换标签”的操作。让我们再次绘制该图:

        ...(some commits)<-o<-o     <-- master
                               \
                                *   <-- HEAD->my_branch
        

        首先,我们需要让HEAD 指向master,我们照常使用git checkout

        git checkout master
        

        导致:

        ...(some commits)<-o<-o     <-- HEAD->master
                               \
                                *   <-- my_branch
        

        现在,假设我们要运行git reset --hard my_branch(我们实际上不这样做,只是看看如果我们运行它会做什么)。这告诉 git “剥离当前分支标签”(读取 READ => 它是 master)“脱离它指向现在的 o 提交,并使其指向与 my_branch 相同的提交”。也就是说,如果我们运行这个命令,我们会得到:

        ...(some commits)<-o<-o
                               \
                                *   <-- my_branch, HEAD->master
        

        请注意,标签已移动,但没有其他任何更改——存储库中的提交仍然相同。

        git merge

        现在让我们回到git merge。不幸的是,git merge 在进行真正的合并时是一个相当复杂的操作。幸运的是,git merge 做的第一件事就是检查它是否是一个非常简单的操作。

        假设我们一直绘制的图形是准确的,这个合并一个简单的操作。特别是,my_branch 指向我们可以通过“滑动标签快进”达到的提交,逆着所有箭头的方向,因此它指向提交*

        ...(some commits)<-o<-o
                               \
                                *   <-- my_branch, HEAD->master
        

        事实证明,这与git reset 所做的相同,但因为git merge 首先检查 看看这是否是一个安全 的事情做,这是我们可能想在这里使用的命令。

        让我们也看看它安全的情况,只是为了完整性。例如,假设我们实际上有这个:

        ...(some commits)<-o<-o<-o   <-- HEAD->master
                               \
                                *    <-- my_branch
        

        在这种情况下,git merge 将进行真正的合并,而git reset --hard 将在master 上丢弃最终的o 提交。我们不能向前滑动标签,我们必须先将其备份,所以从“master 现在所在的位置”到my_branch 的动作不是快进,@987654423 @ 将进行真正的合并。

        git cherry-pick

        最后,为了完整起见,让我们看看如何复制提交。

        一般来说,要复制一个提交,我们使用git cherry-pick。我们先上到我们要复制的分支,比如master:

        ...(some commits)<-o<-o<-o   <-- HEAD->master
                               \
                                *    <-- my_branch
        

        然后运行git cherry-pick my_branch。这会找到my_branch 指向的提交(我们的* 提交)并对其进行复制,将副本添加到当前分支(读取HEAD,参见master,当前分支是master,复制被添加到master)。结果如下所示:

        ...(some commits)<-o<-o<-o<-x   <-- HEAD->master
                               \
                                *       <-- my_branch
        

        其中x* 的副本。

        在所有这些情况下,我们现在可以 git push origin master 将原始提交 * 或其新副本 x 推送到 origin,然后要求 origin 将其 master 重置为我们的新提交。

        拉取 vs 获取

        你提到了“拉”。我建议将其作为两个单独的步骤重新学习,因为git pull 实际上只是这两个步骤:

        1. git fetch
        2. git merge(或者,通常使用更好的命令,git rebase

        实际上是git fetch 步骤联系遥控器,在您的情况下为origin,并从中获取新内容。

        fetch 操作带来了他们拥有的提交,而您没有(并且不会费心带来他们已经拥有的提交)。然后——这不是git push 的镜像——你的git fetch 复制他们的分支信息,但重命名它。他们的master 变成你的origin/master;如果他们有my_branch,它将成为您的origin/my_branch

        此重命名步骤对于允许您合并(或变基)至关重要。如果 fetch 只是覆盖了你的分支,你将失去你所做的新提交的工作!

        获取完成后,您可以将您的工作合并或重新定位到您带来的新提交中。

        我会将所有关于变基的描述留给其他帖子(或 Pro Git 书),但会添加最后一点:除了让正在发生的事情更清楚之外,将git fetch 与第二步分开的原因是这让您有机会决定使用哪个步骤。

        如果您知道您将使用git rebase,您可以通过运行git pull --rebase 将这两个步骤结合起来。

        如果您知道您将运行git merge,您可以通过运行git pull(不带标志)将这两个步骤结合起来。

        但是如果你想先看,然后然后决定呢?然后您需要使用两个单独的步骤,并在这两个步骤之间插入“看看,然后决定”部分。如果您以git pull 开头,则不能这样做。

        (一旦你使用了一段时间的 Git,你可能会知道在 git fetch 之后将使用哪个命令。实际上,它可能通常是 git rebase,并且你可以将 Git 配置为自动使用 --rebase。但请等到你使用 Git 一段时间。)

        【讨论】:

          猜你喜欢
          • 2011-02-15
          • 2011-05-20
          • 2012-07-03
          • 1970-01-01
          • 2017-03-07
          • 2012-04-02
          • 1970-01-01
          • 2013-03-10
          相关资源
          最近更新 更多