Git一遍又一遍地合并提交 [英] Git is merging commits over and over

查看:125
本文介绍了Git一遍又一遍地合并提交的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个拥有两个分支的Git仓库: master Release / v1.0 。在 master 有一个分支策略,我不能直接推送它,我只能通过Pull Requests贡献。



现在,我正在修复Release / v1.0中的一个错误,并且希望将它合并到主文件中。
因此,我执行以下操作:

  //从master创建一个新分支,我将Release / v1.0 
git checkout -b合并到master

//开始合并
git merge origin / Release / v1.0

//合并会自动提交,所以我只需要推送(如果分支不存在远程的话就可以推送到上游)
git push

现在我正在从 merge-to-master master 。 PR完成后,我在 master 中进行了所有更改。



合并按预期工作。但是,当我再次开始合并时,我期望这些提交不再显示,因为它们已经合并。但是提交在合并视图中一次又一次地显示出来。



我假定合并信息的写法不正确?
现在我的问题:我做错了什么?如何避免相同的提交显示一遍又一遍?



@UPDATE:



我想删除一个本地分支( git branch -d v1.0 / 212760-wrong-status - 这是一个功能分支),它告诉我:

 错误:分支'v1.0 / 212760-wrong-status'未完全合并。 
如果您确定要删除它,请运行'git branch -D v1.0 / 212760-wrong-status'。

但是,我已经发布了Release / v1.0(并完成了它),所以我将其视为完全合并。但为什么Git有不同的观点? :)

解决方案

think ,但无法从提供的信息中确定,关键:


我可以[只]通过拉动请求进行捐赠


当您向其他人发送拉请求时,您需要 采取某些措施。我们需要知道他们是谁。谁 他们?让我们来看看他们正在做什么!



让我们从这个开始:



这意味着你已经完成了:

  git checkout -b v1.0 / 212760-错误状态v1.0 

或者在您自己的仓库中具有相同的功能,然后在这里提交一个或两个以修复错误。然后执行以下操作:

  git checkout -b合并到主控制器
git merge origin / Release / v1 .0
git push

步骤。 (如果你画出实际的步骤和实际的提交哈希ID和分支名称,这将有助于很多事情,这样一切都是具体的实际哈希ID。)注意, git push 会将实际的提交推送到其他仓库,比如你称之为 origin 的那个仓库或者你称之为的仓库(大概是不同的/独立的)上游;每次推送都会要求其他 Git设置一些分支名称以指向特定的提交。






在这一点上,我们也给每个人的名字,以便我们知道谁在采取哪种行动。我会给你打电话给Dave,谈谈Dave的提交,它提供了你可以在你的版本库或版本库中看到的特定哈希ID(运行 git log --all --decorate --oneline --graph 查看缩写的散列ID和图)。我没有操作上游存储库的人员的姓名;让我们称她为Ursula,它以U开头为Upstream。

另外,这些天,pull request通常意味着像GitHub或Bitbucket这样的托管服务。 GitHub特别提供了一个clicky按钮,合并请求,并附带一个下拉菜单。点击下拉菜单而不是合并拉动请求按钮提供了三个选项,它们改变了clicky按钮的操作:


  • 合并。这是一个直接合并:Ursula将添加到Ursula(上游)存储库,由Dave的网络托管存储库副本中的Dave创建一个或多个提交。 Dave的提交将具有Dave提交的哈希ID,因为它们是

    DIV的提交。 Ursula将使用一个新的唯一哈希ID创建一个新的提交。

  • 重新合并和合并。这使得Dave的提交的副本成为可能。 Ursula会将这些副本添加到Ursula的存储库中,之后Dave的提交基本上是死的--Dave应该用Ursula的副本替换它们。

  • 壁球和合并。这使得一个新的提交,专属于Ursula,与Dave的 N 提交相同改变(尽管大 N 它只是1)。如果 N = 1,这与rebase and merge非常相似,但默认提交日志消息不同。在任何一种情况下,Ursula的新单一提交都会避免所有Dave的原始提交,就像rebase-and-merge模式一样。




一旦Ursula完成后,您(Dave)可以从您使用该单词拼写的地址中获得 git fetch 她的提交(至少总有一个) 上游。如果她是一个真正的合并,她将合并你所做的提交(我相信) v1.0 / 212760-wrong-status 。也就是说,具有相同散列ID的精确提交现在存在于Ursula的存储库中。她并入她的 master 中有一个不同的 哈希标识符,它可以合并到你的如果你在你自己的计算机资源库中(而不是你的 origin 在GitHub上或其他) ,检查你的 master 并将它快进到她的合并提交中(现在显示,用 git log --all --decorate --oneline - -graph ,在你的 upstream / master 上),然后运行:

  git branch -d v1.0 / 212760 -attributes 

您的Git将会看到你的 v1.0 / 212760-wrong-status 的提示合并到你当前的分支。也就是说,通过查看Ursula的合并提交的第二个父代,您的Git可以跟踪从 master 到该特定提交的直接行。因此,提交包含在 master 中,Git很乐意删除 v1.0 / 212760错误



由于不是这种情况,我们可以得出结论:厄休拉必须已经使用clicky按钮的rebase and merge或squash and merge模式来创建提交的副本。如果副本足够好 - 如果您对Ursula复制提交的方式感到满意 - 您可以安全地强制删除您的分支名称,失去原始提交(最终永远保留,尽管您的推荐日志可能会保留约30天左右,如果换句话说,如果Ursula已经将您的提交复制到了一个新的可以改进的提交中,从而避免了原始提交,现在由Dave决定是否应该抛弃Dave的原始提交来支持这个新副本。这就是你的Git告诉你的。



如果你放弃你自己的提交,你的 next >拉取请求可能 - 取决于你如何构建它 - 重新引入这个提交。像往常一样,它是否将取决于实际提交图。提交图 - git log --graph 绘制的图 - 是最重要的。您通过您的拉取请求提供实际提交,它们随实际图段一起提供。 如果他们接受了实际的提交,你的图段将被添加,现在你和他们共享图表。但是如果他们不提交你的提交,他们会添加一些其他提交不同的图段。你的Git会将他们的提交添加到你的图中,为你提供一个更大的包含提交副本的图。这取决于你决定如何处理这个问题。


I have a Git repository with two branches: master and Release/v1.0. On master there's a branch policy that I cannot directly push to it, I can just contribute through Pull Requests.

Now, I'm fixing a bug on Release/v1.0 and want to merge it to master. Therefore I do the following:

// create a new branch from master where I merge the changes from Release/v1.0
git checkout -b merge-to-master

// start the merge
git merge origin/Release/v1.0

// merge gets committed automatically, so I just need to push (to upstream if the branch doesn't exist remotely)
git push

Now I'm making a Pull Request from merge-to-master to master. Once the PR is completed, I have all changes in master.

The merge works as expected. However, When I start the merge once more, I would expect that those commits do not show up again, because they have already been merged. But the commits are showing up again and again in the merge view.

I assume that the merge info is not written correctly? Now my question: Am I doing something wrong? How do I avoid the same commits to show up over and over?

@UPDATE:

also, when I want to delete a local branch (git branch -d v1.0/212760-wrong-status - which is a feature branch), it tells me:

error: The branch 'v1.0/212760-wrong-status' is not fully merged.
If you are sure you want to delete it, run 'git branch -D v1.0/212760-wrong-status'.

But, I already made a PR to Release/v1.0 (and completed it), so I would consider it as fully merged. But why is Git having a different opinion? :)

解决方案

I think, but cannot be sure from the information provided, that this is the key:

I can [only] contribute through Pull Requests

When you deliver a pull request to someone else, you are asking them to take some action. We need to know who the them is. Who are they? Let's find out what, precisely, they are doing!

Let's start with this:

v1.0/212760-wrong-status

I think this means you have done:

git checkout -b v1.0/212760-wrong-status v1.0

or equivalent in your own repository, and then made a commit or two here to fix a bug. You then do the:

git checkout -b merge-to-master master
git merge origin/Release/v1.0
git push

steps. (It will help a great deal if you draw out the actual steps and actual commit hash IDs and branch names involved here, so that everything is concrete with actual hash IDs.) Note that git push will push the actual commits to some other repository, such as the one you call origin or the (presumably different / separate) one you call upstream; each push will ask that other Git to set some branch name(s) to point to specific commits.


At this point, let's also give everyone names so that we know who is taking which action. I will call you Dave and talk about Dave's commits, which have the specific hash IDs you can see in your repository or repositories (run git log --all --decorate --oneline --graph to see the abbreviated hash IDs and the graph). I don't have a name for the person operating the upstream repository; let's call her Ursula, which starts with U for Upstream.

Furthermore, these days, "pull request" usually implies a hosting service like GitHub or Bitbucket. GitHub in particular offers a clicky button, "merge pull request", with a pulldown menu attached to it. Clicking on the pulldown menu rather than the "merge pull request" button offers three options, which change the action of the clicky button:

  • Merge. This is a straight merge: Ursula will add to Ursula's (upstream) repository, one or more commit made by Dave from Dave's web-hosted repository copy. Dave's commit(s) will have the hash IDs of Dave's commits, because they are Dave's commits. Ursula will create one new commit with one new, unique hash ID.

  • Rebase and merge. This makes copies of Dave's commits. Ursula will add these copies to Ursula's repository, after which Dave's commits are essentially dead—Dave should replace them with Ursula's copies.

  • Squash and merge. This makes one single new commit, belonging exclusively to Ursula, that makes the same changes as Dave's N commits (however large N is, even if it's just 1). If N = 1 this is remarkably similar to "rebase and merge", though the default commit log message is different. In either case, Ursula's new single commit obviates all of Dave's original commits, just as with the rebase-and-merge mode.

Once Ursula has finished, you (Dave) can git fetch her commit(s)—there's always at least one of hers—from the address you spell using the word upstream. If hers is a true merge, she will have merged the commit you made (I believe) on v1.0/212760-wrong-status. That is, that exact commit, with its same hash ID, is now present in Ursula's repository. Her merge into her master has a different hash ID from your merge into your master, but it does use your original commit.

If you then, in your own repository on your computer (not your origin on GitHub or whatever), check out your master and fast-forward it to her merge commit (now showing, with git log --all --decorate --oneline --graph, on your upstream/master) and then run:

git branch -d v1.0/212760-wrong-status

your Git will see that the commit that is the tip of your v1.0/212760-wrong-status is merged to your current branch master. That is, by looking at Ursula's merge commit's second parent, your Git can trace a direct line from your master to that particular commit. So that commit is contained in master, and Git will be happy to delete the name v1.0/212760-wrong-status from your local repository.

Since this isn't the case, we can conclude that Ursula must have used the "rebase and merge" or "squash and merge" mode of the clicky button to make a copy of your commit. If the copy is good enough—if you are happy with the way Ursula copied your commit—you can safely forcibly delete your branch name, losing your original commit (eventually forever though your reflogs will probably retain it for another 30 days or so, if you change your mind).

In other words, if Ursula has copied your commit to a new and supposedly improved commit that obviates your original commit, is is now up to you—Dave—to decide whether Dave's original commit should be discarded in favor of this new copy. That's what your Git is telling you.

If you don't discard your own commit like this, your next pull request could—depending on how you build it up—re-introduce this commit. Whether it will depends, as usual, on the actual commit graph. The commit graph—the one that git log --graph draws—is what matters. You provide actual commits, which come with actual graph segments, through your pull requests. If they take your actual commits, your graph segments get added, and now you and they share graphs. But if they don't take your commits, they'll add some other commits with different graph segments. Your Git will add their commits to your graph, giving you an ever-bigger graph with lots of copies of commits. It's up to you do decide how you wish to deal with that.

这篇关于Git一遍又一遍地合并提交的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆