git:推送单个提交、使用 rebase 重新排序、重复提交 [英] git: Pushing Single Commits, Reordering with rebase, Duplicate Commits

查看:75
本文介绍了git:推送单个提交、使用 rebase 重新排序、重复提交的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将几个单一的提交推送到一个 git 远程仓库.我按照 Geoff 的回答在这里找到了这样做:

I want to push several single commits to a git remote repo. I followed Geoff's answer found here to do so:

如何将特定提交推送到远程,而不是之前的提交?

我要推送的提交不在前面,所以我必须先使用 rebase 重新排序提交,我使用这些说明来这样做:

The commits I want to push are not at the head, so I have to reorder the commits using rebase first and I used these instructions to do so:

http://gitready.com/advanced/2009/03/20/reorder-commits-with-rebase.html

基本上我已经完成了:

git clone
git commit
git commit
...
git pull
git rebase -i HEAD~3
git push origin <SHA>:master

我在执行此操作时出错.所以我开始深入研究这个问题.如果我在 rebase 后执行第二次 git pull,我发现我的日志中有重复的提交,例如:

I got errors doing this. So I started looking deeper into the problem. I found that there are duplicate commits in my log if I do a second git pull after rebasing, for example:

git clone
git commit
git commit
...
git pull
git log --pretty=format:"%h - %an : %s" // log before rebasing
git rebase -i HEAD~3
git pull
git log --pretty=format:"%h - %an : %s" // log after rebasing
git pull 
git log --pretty=format:"%h - %an : %s" // log after rebasing after pulling

所以我发布了这个问题:

So I posted this question:

git:本地变基后拉取重复提交

Roger 的回答让我想到了这个问题:为什么我在 rebase 和 pull 后看到重复的提交?

Roger's response there led me to this question: Why do I see duplicate commits after rebasing and pulling?

从上面看,变基前的日志如下:

From above, the log before rebasing looks like:

84e4015 - Me : Local Commit 3
0dbe86a - Me : Local Commit 2
d57ba2a - Me : Merge branch 'master' of remote repository
a86ea35 - Me : Local Commit 1 before reordering
2fc4fe7 - Remote User 2 : Remote Commit 2
b7a8656 - Remote User 1 : Remote Commit 1
8ce80fc - Me : Merge branch 'master' of remote repository

变基后的日志如下:

cf1ff7b - Me : Local Commit 3
cd14463 - Me : Local Commit 2
b9d44fb - Me : Local Commit 1 after reordering
9777c56 - Remote User 2 : Remote Commit 2
a2d7d8b - Remote User 1 : Remote Commit 1
8ce80fc - Me : Merge branch 'master' of remote repository

注意原来的 2 次提交 2fc4fe7 和 b7a8656 有新的 SHA;9777c56 和 a2d7d8b.我相信这是问题的开始.

Notice that the original 2 commits 2fc4fe7 and b7a8656 have new SHAs; 9777c56 and a2d7d8b. I believe this is the start of the problem.

现在,在我执行另一个 git pull 后,日志如下所示:

Now after I do another git pull the log looks like this:

e8e1a85 - Me : Merge branch 'master' of remote repository
cf1ff7b - Me : Local Commit 3
cd14463 - Me : Local Commit 2
b9d44fb - Me : Local Commit 1 after reordering
9777c56 - Remote User 2 : Remote Commit 2
a2d7d8b - Remote User 1 : Remote Commit 1
2fc4fe7 - Remote User 2 : Remote Commit 2 // duplicate 2
b7a8656 - Remote User 1 : Remote Commit 1 // duplicate 1
8ce80fc - Me : Merge branch 'master' of remote repository

请注意,远程提交现已复制,并且远程提交的原始 SHA 2fc4fe7 和 b7a8656 已返回.

Notice that the remote commits are now duplicated, and the original SHAs of the remote commits, 2fc4fe7 and b7a8656, have returned.

在 Roger 的回应中,他说这看起来像是其他人推送到 git 的错,并且他们正在重新定位他们已经推送的提交.但我相信在本地重新定位推送的提交是我的错.

In Roger's response he said that it looked like the fault of other people pushing to git and that they were rebasing their already pushed commits. But I believe it is my fault for locally rebasing a pushed commit.

这是因为我重新设置了已经推送到远程的提交吗?如果是这样,我应该怎么做才能避免这种情况?我需要重新提交我的提交,以便我可以推送一个提交.我应该使用分支系统来执行此操作吗?如果是这样,我将如何使用分支来解决这个问题?

Is this because I rebased a commit that had already been pushed to the remote? If so, what should I have done to avoid this? I need to rebase my commits so that I can push a single commit. Should I have used a branching system to do this? If so how would I use branches to solve this problem?

推荐答案

简而言之,rebase 不会更改 提交,1 而是复制它们.Git 通常会隐藏原件,但如果您的原件包括其他用户共享的原件,您(当然还有他们)仍然可以看到这些原件.

The short answer is that rebase does not change commits,1 but rather copies them. Git normally then hides away the originals, but if your originals include those shared by other users, you (and of course they) and still see those originals.

作为一般规则,您应该只对自己的私有、未发布的提交进行变基.由于没有人 else 根据定义拥有这些副本,因此您制作自己的副本然后(通过变基)隐藏您的原件这一事实不是问题:您现在看到的是您的副本而不是您的原件,其他人也看不到,如果需要,您可以继续变基.但是,一旦您发布(通过 push 或类似方式)提交,您就不能再更改它,因为其他人现在拥有您的原始副本,包括其 SHA-1 ID,并且他们以后还会有的.

As a general rule, you should only rebase your own private, unpublished commits. Since no one else has a copy of these by definition, the fact that you make your own copies and then (via rebase) hide away your originals is not a problem: you now see your copies instead of your originals, and no one else sees either, and you can continue to rebase if needed. As soon as you publish (via push or similar) a commit, though, you can no longer change it, because someone else now has a copy of your original, including its SHA-1 ID, and they will still have it later.

在这种情况下,您所做的是重新设置(即复制)他们的 提交以及您自己的提交.部分问题源于使用 git pull,这意味着获取然后合并",而您想要的是获取然后变基".您可以单独执行这些步骤:

What you've done in this case is to rebase (i.e., copy) their commits as well as your own. Part of the problem stems from using git pull, which means "fetch then merge", when what you wanted was "fetch then rebase". You can either do the steps separately:

git fetch
git rebase

或使用 git pull --rebase:

git pull --rebase

它告诉 pull 脚本在执行 fetch 之后,它应该执行 rebase 而不是合并.您也可以将 git 配置为自动执行此操作,无需 --rebase 参数.2

which tells the pull script that after doing the fetch, it should do a rebase instead of a merge. You can also configure git to do this automatically, without the --rebase argument.2

现在的主要问题是您可能不想要一个合并.如果是这样,您将需要撤消"该合并(使用 git reset;请参阅其他 stackoverflow 帖子).

The main problem right now is that you have a merge you probably didn't want. If so, you will need to "undo" that merge (with git reset; see other stackoverflow postings).

1它不能:一个 git 对象,包括一个提交,是由它的对象 ID 命名的,它是其内容的加密校验和.提交由其父 ID、树的 ID、提交的作者和提交者(姓名、电子邮件和时间戳)以及提交消息组成.如果您更改其中任何一项,您将获得具有不同 ID 的新的不同提交.

1It can't: a git object, including a commit, is named by its object ID, which is a crypographic checksum of its contents. A commit is comprised of its parent ID(s), the ID of the tree, the commit's author and committer (name, email, and timestamp), and the commit message. If you change any of these, you get a new, different commit with a different ID.

2您甚至可以将其配置为使用 git pull --rebase=preserve.但是,跨 rebase 操作保留合并是一个单独的主题(我之前在 stackoverflow 帖子中已经讨论过).

2You can even configure it to use git pull --rebase=preserve. However, preserving merges across rebase operations is a separate topic (which I've covered somewhat before in stackoverflow postings).

这篇关于git:推送单个提交、使用 rebase 重新排序、重复提交的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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