Search code examples
gitgithubmergeversion-controlbitbucket

Git merging in intelligent way


I'm new here and just wondering around in git.

Recently, I got a chance to work on a huge repository. (I believe it can be ranked in global git history as well to be that huge) The repo is having average of 3-5 commits per minute.(no kidding here)

lets get back to problem,

As repo is huge we maintain a PR based merging meaning, no one can directly commit on pre-defined 5 branches. when we try to commit on the develop branch we need to create a custom feature branch and it is regularly out of sync so to avoid that while developing we are pushing the empty branch first. resulting in following scenario on local.

Mainline branch 

a--b--c--d--e--f--g--h      --i--j
                       -1--2 (custom/feature branch)

so in given case I want my branch (custom/feature branch) to be like

a--b--c--d--e--f--g--h--k--l--1--2

I know a way to achieve this where we are doing following operations on custom branch

git reset --hard~2
git pull origin Mainline --ff-only
git reflog | grep "commit"
git cherry-pick ######1
git cherry-pick ######2

given method ensures that I haven't lost any of my commits and my branch is synced with the Mainline branch without any merge commits.

So the question here is "It's been hectic to do this for all the commits/branches, so is there any way we can have it done through 1-2 commands?"

I was also confused about the behaviour of the git, as we are using bitbucket web-interface it shows us whenever conflict occurs in PR section while merging the custom branch to mainline branch.

So the doubt here is that, is it necessary to keep the custom branch updated? (as we are using recursive strategy for merging I don't feel it is absolutely necessary.)


Solution

  • So the question here is "It's been hectic to do this for all the commits/branches, so is there any way we can have it done through 1-2 commands?"

    $ git fetch origin Mainline
    $ git rebase origin/Mainline
    

    Beware that this will not update the “local” Mainline, but if you are not supposed to work in it directly you might as well delete it and only keep the remote.

    If you have multiple useful branches you may want to leave the branch name out and add -p (--prune) to fetch e.g.

    $ git fetch -p origin
    

    This will update all branches tracking origin, and will automatically delete (prune) the ones which have been deleted.

    If you have multiple remotes, you may want to replace origin with --all, keeping the -p, in the same command: --all will go through every remote and update all their branches.

    git pull --rebase origin Mainline should also work, but I'm not fond of git pull, I'd rather perform the "synchronise with remote" and "update local branches" steps separately and explicitly.

    I'm a bit surprised that this would not be provided as an example workflow by the contributor documentation or training.

    So the doubt here is that, is it necessary to keep the custom branch updated? (as we are using recursive strategy for merging I don't feel it is absolutely necessary.)

    Technically? No, git doesn't care.

    If this is mandated by the project's contribution guidelines though there may be practical reasons for it e.g. history visualisation tools tend to have trouble with many branches overlapping one another, this is a way to avoid branches overlapping as a branch basically always spans two commits.

    If I mandated this, I would add tooling to do it automatically though (some variant or mode of a "merge bot").