上次 git 合并后的 git rebase

发布于 2024-11-13 22:20:20 字数 346 浏览 2 评论 0原文

我有以下情况:

  • 我从主存储库(X)创建了一个克隆(Y),因为有很多人在Y上工作,我们没有做任何rebase但只有合并。当我们想要将 Y 传递(push) 到 X 时,我们希望进行一次rebase,以便让事情变得漂亮和干净。

问题是,当进行rebase时 我们被要求进行之前的merge 步骤中已经完成的所有合并。除了实际上重新进行合并的解决方案之外,还有其他解决方案吗?

我预计它会非常简单,因为我们已经解决了冲突的合并。

I have the following situation:

  • I created a clone(Y) from a main repository(X), because there were many people working on Y we didn't do any rebase but only merges. When we want to deliver(push) Y to X we would like to do a rebase in order to have things nice and clean

The problem is that when doing rebase we are asked to do all the merges that we already did in the previous merge steps. Is there a solution to this, beside the one that means actually re-doing the merges?

I expected it to be pretty straightforward since we already solved the conflicting merges.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

池木 2024-11-20 22:20:20

git merge --squash 现在是我在进行大量工作和多次合并后进行变基的首选方式(请参阅此答案)。如果您正在处理的分支名为 my-branch 并且您想从 main 变基,那么只需执行以下操作:

git checkout my-branch
git branch -m my-branch-old       # rename from my-branch to my-brand-old
git checkout main
git checkout -b my-branch         # make new my-branch branch
git merge --squash my-branch-old  # squash and merge changes from old branch 
git commit

git merge --squash is now my preferred way of rebasing after a large amount of work and many merges (see this answer). If the branch you're working on is called my-branch and you want to rebase from main then just do the following:

git checkout my-branch
git branch -m my-branch-old       # rename from my-branch to my-brand-old
git checkout main
git checkout -b my-branch         # make new my-branch branch
git merge --squash my-branch-old  # squash and merge changes from old branch 
git commit
眉目亦如画i 2024-11-20 22:20:20

通过变基来获得“干净”的历史被高估了。如果您想保留历史记录,最好的方法就是进行合并而不是变基。这样,如果您需要返回修订版本,它就会与您在开发过程中测试的版本完全相同。这也解决了您之前解决的合并冲突的问题。

如果您不关心保留历史记录,您可以从 master 创建一个新分支,检查它,然后执行 git read-tree -u -m dev 来更新您的工作树以匹配dev 分支。然后你可以将所有内容提交到一个大提交中,并像平常一样将其合并到 master 中。

Rebasing to get a "clean" history is overrated. The best way if you want to preserve history is just to do the merge instead of a rebase. That way if you ever need to go back to a revision, it is exactly the same as the one you tested during development. That also solves your issue about the previously solved merge conflicts.

If you don't care about preserving history, you can create a new branch off of master, check it out, then do a git read-tree -u -m dev to update your working tree to match the dev branch. Then you can commit everything into one big commit and merge it into master as normal.

虫児飞 2024-11-20 22:20:20

两点注释:

Two remarks:

  • you can rebase your own (non yet pushed) work as many time as you want on top of newly fetched commits.
  • You could avoid the merge conflicts (during rebase) if you had activated git rerere, which is done for this kind of situation.
    http://git-scm.com/images/rerere2.png
    See more at git rerere.
故事未完 2024-11-20 22:20:20

您可以将分支中的所有更改放入 master 中的新提交中,方法如下:

git diff master > my_branch.patch
git checkout master
patch -p1 < my_branch.patch

然后暂存文件并提交。

You can take all of the changes in your branch and put them into a new commit in master with the following:

git diff master > my_branch.patch
git checkout master
patch -p1 < my_branch.patch

Then stage your files and commit.

梅窗月明清似水 2024-11-20 22:20:20

关于合并冲突的重播,您可以使用 git rerere 来维护一个关于如何解决合并冲突的数据库,这样执行导致相同冲突的 rebase 就会自动为您完成繁琐的部分。

https://hackernoon.com/fix-conflicts-only-once -with-git-rerere-7d116b2cec67

git config --global rerere.enabled true

需要注意的一件事是,如果您错误地解决了某些问题,它会下次也会自动为你无聊,而你可能并没有真正意识到。

更正式的文档在这里:https://git-scm.com/docs/git-rerere

Regarding the replay of merge conflicts, you can use git rerere to maintain a database of how merge conflicts have already been solved, so that performing a rebase that results in the same conflicts will have the laborious parts done for you automatically.

https://hackernoon.com/fix-conflicts-only-once-with-git-rerere-7d116b2cec67

git config --global rerere.enabled true

The one thing to look out for is that if you resolved something incorrectly it will be automatically borked for you next time too, and you may not really realize it.

More formal documentation here: https://git-scm.com/docs/git-rerere

笑红尘 2024-11-20 22:20:20

我发现@sky 的回答很有帮助。我把它变成了一个压缩变基函数。

假设您位于 your-branch 上,它的作用是创建一个分支 your-branch-tmp,它是执行 merge --squash 的结果> 在主线上。它还保留所有提交消息并允许您进行编辑。重要的是,它也不会影响您当前的分支。

运行squash-rebase后,如果您对它所做的感到满意,则必须对tmp分支进行硬重置。那么实际上你已经完成了一次壁球变基。

function squash-rebase() {
  MESSAGES="$(git log $(git merge-base main HEAD)..HEAD --reverse --format=%B)"
  SRC_BRANCH="$(git_current_branch)"
  TMP_BRANCH="$(git_current_branch)-tmp"
  echo "creating temp branch $TMP_BRANCH from $(git_current_branch)"
  git checkout -b $TMP_BRANCH main  # create tmp branch from main and checkout
  git merge $SRC_BRANCH --squash
  git commit -m "$MESSAGES" -n
  git commit --amend -n # just so you can edit the messages
  git checkout $SRC_BRANCH
  echo "IMPORTANT: run git reset --hard $TMP_BRANCH to complete squash rebase."
  echo "First, though, you may run git diff $TMP_BRANCH to make sure no changes."
  echo "Finally, delete the tmp branch with git branch -D $TMP_BRANCH"
}

注意:假设您使用的是 oh-my-zsh,否则您可能需要找到其他方法来获取当前分支名称。

I found @sky's answer helpful. And I made it into a squash-rebase function.

Assuming you are on your-branch, what this does is create a branch your-branch-tmp that is the result of doing merge --squash on main. It also preserves all the commit messages and lets you edit. Importantly, it also leaves your current branch alone.

After running squash-rebase, if you're satisfied with what it did, you must do a hard reset to the tmp branch. Then in effect you've completed a squash rebase.

function squash-rebase() {
  MESSAGES="$(git log $(git merge-base main HEAD)..HEAD --reverse --format=%B)"
  SRC_BRANCH="$(git_current_branch)"
  TMP_BRANCH="$(git_current_branch)-tmp"
  echo "creating temp branch $TMP_BRANCH from $(git_current_branch)"
  git checkout -b $TMP_BRANCH main  # create tmp branch from main and checkout
  git merge $SRC_BRANCH --squash
  git commit -m "$MESSAGES" -n
  git commit --amend -n # just so you can edit the messages
  git checkout $SRC_BRANCH
  echo "IMPORTANT: run git reset --hard $TMP_BRANCH to complete squash rebase."
  echo "First, though, you may run git diff $TMP_BRANCH to make sure no changes."
  echo "Finally, delete the tmp branch with git branch -D $TMP_BRANCH"
}

Note: assumes you are using oh-my-zsh, otherwise you may have to find another way to get current branch name.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文