Merging branch back with clean history

I am working on a branch (with others) off of master.

A - B - C - F - G    (master)
         \
          D - E      (branch-a)

Periodically, we merge master into the branch, to minimize conflicts later.

  • JGit: Checkout a remote branch
  • Suddenly every git command causes `error: bad signature` in every Git repository
  • How to patch all changed files before a commit in Git
  • Possible pull request workflow to merge a branch into master
  • Git clean and smudge filters don't do anything
  • Ignore a versioned file from a Git repository and its clones
  • A - B - C - F - G    (master)
             \       \
              D - E - H  (branch-a)
    

    Eventually, we will want to merge back.

    A - B - C - F - G - I - K - M - N  (master)
             \       \       \     /
              D - E - H - J - L - O    (branch-a)
    

    What is the cleanest way I can merge back into master?

    1. I want to preserve the individual commits (i.e. no squash)
    2. I will not use branch-a any longer, so commits hashes can change.
    3. I would like to not include merge commits (e.g. H, L) for merges without conflicts, if possible.

    Ideally, it would look like this (assuming there were no conflicts):

    A - B - C - F - G - I - K - M - N  (master)
             \                     /
              D  -  E   -   J  -  O
    

    Any ideas on how this should be done?

    (FYI, this is a question about my workflow. If I should have done something else earlier, that is a legitimate answer too.)


    UPDATE:

    After thinking about this some more, I realized this is often not possible.

    For example, if J changed a line that G changed, there would not be a way to get that history.

    The next best choice would be to have this history:

    A - B - C - F - G - I - K - M - D - E - J - O  (master)
    

    Essentially, this is a rebase, but omitting unnecessary merge commits.

  • What do I gain by using git lfs?
  • Problems with accents and special characters in Git
  • How do I have github build a project page automatically from a folder in the master branch?
  • Git clone failed with “refs/heads/master does not point to a valid object”
  • how to extract changeid using git log --format=?
  • Cloning from Github to a specific directory results in an empty directory. Where are the files?
  • 2 Solutions collect form web for “Merging branch back with clean history”

    You can do this by hand by branching off E and cherry-picking the other commits into the new branch, then merging that into master. Rebasing is also possible, i.e. do

    git rebase C
    

    on branch-a. However, that will take commits from master and put them on your feature branch.

    git rebase -i C
    

    has the same effect, but allows you to skip commits that you are no are from master and are not required on branch-a. Git cannot in general know whether commits interact in any way (e.g. a change to one file might require a change to a different file that was done on master), so there’s no fail-safe, fully automatic solution to this problem.

    you could do this when you merge master into your working branch

     git pull --rebase
    

    when your commits are done on your working branch and you want to pull code from master into your branch. You could also configure this behaviour as default on certain branches by doing

    git config branch.master.rebase true
    

    This will ensure that your commits are always reapplied so your history says linear. That is, your commits will be at the top when you eventually raise a pull request and the history will be clean with no un-necessary merge commits polluting it. Another advantage is, it is easier to cherry-pick if you want to maintain two or more branches in sync.

    Git Baby is a git and github fan, let's start git clone.