0

if I have a workspace looks like this:

oliver-koo-C02WC0EJHTDG:foo oliver.koo$ git log --all --decorate --oneline --graph
* f528ce3 (HEAD -> master) someone else made a change
| * 447855b (feature1.2) feature 1.2
| | * f3e4d2f (feature-1.1) create feature 1.1
| |/  
| * b04c5c6 (feature-1) create feature 1 core
|/  
* 06a8ddb (origin/master, origin/HEAD) Update stuff

and each branch track's parent branch like so:

oliver-koo-C02WC0EJHTDG:foo oliver.koo$ git branch -vv
  feature-1   b04c5c6 [master: ahead 1, behind 1] create feature 1 core
  feature-1.1 f3e4d2f [feature-1: ahead 1] create feature 1.1
  feature1.2  447855b [feature-1: ahead 1] feature 1.2
* master      f528ce3 [origin/master: ahead 1] someone else made a change

is there a way (or even possible) to recursively merge master into all the child branch without checking out each child branch and do a git merge master?


Note:

  1. This answer suggest using git fetch . master:feature-x wouldn't work since these are non fast-forward merge
oliver-koo-C02WC0EJHTDG:foo oliver.koo$ git fetch . master:feature-x
From .
 ! [rejected]        master          -> feature-x  (non-fast-forward)
  1. I know achieve similar result with rebase without checkout (git rebase master feature-x). but I want to use merge.

  2. I been thinking alternative using git cherry-pick A^..B but again is it possible to apply cherry-picked commits to a branch without checking it out?

OLIVER.KOO
  • 5,654
  • 3
  • 30
  • 62
  • 2
    Not possible. `git merge master` merges `master` into **the currently checked out branch**, you cannot even name the branch to merge to. The same for `cherry-pick`. See https://stackoverflow.com/a/4157106/7976758: "*A checkout of the target branch is necessary to allow you to resolve conflicts, among other things (if Git is unable to automatically merge them).*" – phd Jun 07 '19 at 05:29
  • @phd do you know if there are documentation to support that comment "A checkout of the target branch is necessary to allow you to resolve conflicts, among other things (if Git is unable to automatically merge them)." – OLIVER.KOO Jun 07 '19 at 05:31
  • 1
    The short answer is no; the long answer is *use `git worktree add` to add additional work-trees on each branch so that you have a checkout of the branch*. – torek Jun 07 '19 at 06:14

1 Answers1

1

If you mean "without checking out all the files in each branch", yes. Merge does need to examine potential conflicts and might need to leave them for you to examine/fix up, so it does need a work tree, but you don't have to check out all the files, you can just set up the index and HEAD and leave the work tree empty.

What this means is, you can do the merging very cheaply in a tmpfs clone.

rm -rf ${scratchmerge=`mktemp -d`}
git clone -nsb branch1 $scratchmerge  # minimal clone, <1MB even for the linux repo
cd $_
git reset -q
git merge master
fix any conflicts and commit if needed
git push
cd -

The -n option makes the clone not do a checkout, so the work tree stays empty (and the index isn't read in), the -s option makes the clone share the origin's object db, which is exactly what you want for scratch work like this, and the -b option sets HEAD, the checked-out branch. All in all, that clone uses a few tens of kbytes total (for the clone's refs plus the repo scaffold).

The git reset -q loads the index from the HEAD commit, you could equivalently git read-tree HEAD here and for a script that'd be more pedantically correct, it's the core-command equivalent.

And from there it's normal: merge, fix conflicts, push.

jthill
  • 55,082
  • 5
  • 77
  • 137