tonilopezmr / tonilopezmr.github.io

My web portfolio.
https://tonilopezmr-github-io.vercel.app
Other
4 stars 1 forks source link

Merge sequential branches using rebase #11

Open tonilopezmr opened 6 years ago

tonilopezmr commented 6 years ago

07/03/2018

The current branches are:

> git branch
master
A
B

When you want to merge with squash like this B - squash -> A - squash -> master you need to follow this steps:

  1. Merge with squash A to master
  2. Pulls data to master branch
  3. Search the last commit message from A
  4. Move to B branch and copy the commit id for the commit with the commit message you are looking in 3.
  5. Then you can execute this command git rebase --onto master <last commit message from A> B in the B branch
  6. Then you can push your changes on your remote branch with git push -f, the changes will apply then you can merge directly B to master πŸ‘

Update - 05/06/2018

Now, you can use @Serchinastico amazing gist to do the steps above automatically with a script in .gitignore.

https://gist.github.com/Serchinastico/98cea9fcc2733689e63c57191257bd2c

tonilopezmr commented 1 year ago

This changed a lot since I'm using Graphite, It'll update the branches automatically, with a single command.

You can learn more in the Getting Started docs.

Summary

Setup

$ gt user branch-prefix --set kevin/
$ gt user editor --set vim
$ gt auth --token <PASTE>

# Optional (use original commit date/author on internal rebase/restack)
$ gt user restack-date --use-author-date

Workflow

$ gt bco main
 # do work
$ git add .
$ gt bc wip/foo-bar-baz
 # do more work
$ git add .
$ gt cc -m "something"
 # branch is probably ready to submit but I have related work to do
$ gt b rename kevin/foo-bar-baz
 # do related work
$ git add .
$ gt bc wip/new-stack
 # more work
$ git add .
$ gt ca
$ gt b rename kevin/new-stack
 # ready to submit the whole stack
$ gt ss

It’s not uncommon for me to have multiple unrelated wip branches. For example my current seaplane repo looks like this:

$ gt l
β—― kevin.asyncify PR #118 (Draft)
β”‚ [DO NOT MERGE] Convert to async
β”‚ 4 days ago
β”‚ * a4fc67 - update doc examples to async
β”‚ * 47dd62 - update api tests to async
β”‚ * 12cb09 - makes the SDK async
β”‚
β”‚  β—― wip.formation-configuration-command
β”‚  β”‚ 4 days ago
β”‚  β”‚ * 419062 - stub formation configuration commands
β”‚  β”‚
β”‚  β”‚  β—‰ wip.init-ui-tests (current)
β”‚  β”‚  β”‚ 4 days ago
β”‚  β”‚  β”‚ * 40cb81 - init-ui-test: adds base init tests
β”‚  β”‚  β”‚
β”‚β”€β”€β”΄β”€β”€β”˜
β”‚
β—― main
β”‚ 4 days ago
β”‚

Useful/Most Used Commands

More specialized command are the gt ds and gt us (downstack/towards main and upstack/away from main) which I primarily use with sync so... gt dss [-u] or gt uss [-u].

Merging a Stack!

[(Graphite has added some docs on merging stacks from their web UI now)](https://docs.graphite.dev/guides/graphite-dashboard/merging-your-pull-requests#merging-a-stack-of-prs)

So your PR was approved πŸŽ‰Β Now you’re ready to merge. But wait!

The best method to merge stacked PRs is either bottom to top (closest to main to furthest way from main). One could also use a top to bottom (furthest away from main down to main) approach, but you lose some benefits in stacked PRs (i.e. the end result in main is a single squashed PR from all stacks).

⚠️ Do not merge a stacked PR without the base branch (the PR immediately below it, or closer to main) having been approved first! ⚠️

Example Merge

Imagine a stack of Three PRs which Graphite displays at the command line roughly this:

$ gt l
β—‰ kevin.branch-3 (current) PR #3
β”‚ 4 days ago
β”‚ * a4fcef - even more work
β”‚
β—― kevin.branch-2 PR #2
β”‚ 4 days ago
β”‚ * b2fc11 - some more work
β”‚  
β—― kevin.branch-1 PR #1
β”‚ 4 days ago
β”‚ * c5fc67 - some work
β”‚
β—― main
β”‚ 4 days ago

Or in the PR comment displayed like:

β—‰ main
    β—― PR branch-1 #1 Graphite (this PR)
        β—― PR branch-2 #2 Graphite 
            β—― PR branch-3 #3 Graphite 

Example Merge with Rebase

Sometimes after you merge a base branch, the branch/PR above it contains merge conflicts as reported by Github. In these situations my workflow generally looks like this:

$ gt rs
  # Pull down the latest, including the recent merge
  # pick 'y' to delete old merged branches
$ gt l
  # Make sure Graphite automatically rebased in-flight PRs to stay
  # above 'main'
  # You can see this by if your open PRs are above or below 'main'

  # if they have fallen below 'main' and Graphite didn't automatically
  # fix them up
$ gt bco my-next-pr-branch
  # check out the PR branch that is next up
$ gt sr
  # rebase onto main
  # do any normal rebase fixing required, potentially with rounds
  # of 'gt continue' (git rebase --continue)
$ gt ss [-u]
  # Ensure the in-flight PRs are updated appropriately
  # 
  # Add -u if you have branches in the stack that do not have active PRs