Q: How do I add a parent to a commit in git? I recently rebranched - that is, created a new branch off master and merged in a feature branch, e.g. TASK-123, with the new branch, TASK-123-b, replacing the feature branch that was merged into it. This is a regular action in our git workflow whenever a feature branch conflicts with master.
When I merged TASK-123 into TASK-123-b, there was of course a merge conflict, which I've resolved and then committed. The new branch, TASK-123-b, and the commit merging in TASK-123, only have one parent: master
How can I modify the commit so that both master and TASK-123 are its parents? I assume git rebase will be involved, but beyond that I don't know how to add a parent branch/commit to a commit.
My commit history currently looks like this:
    master -*---*-----* ...
             \         \
  TASK-123    *---*-*   \
                         \   
TASK-123-b                * ...

I want my commit history to look like this:
    master -*---*-----* ...
             \         \
  TASK-123    *---*-*   \
                     \   \   
TASK-123-b            \---* ...

Note: I haven't pushed TASK-123-b to a remote yet, so rebasing commits on it should cause no problems with my coworkers.

A: You need to redo the merge of TASK-123 into TASK-123-b because it looks like it didn't work like you wanted it to. To do that, find the commit hash in TASK-123-b just before the merge and reset your branch pointer there:
$ git checkout -B TASK-123-b abc123

Then repeat the merge:
$ git merge TASK-123

If you reset the branch pointer, the old merge commit is going to be orphaned and won't show up in the logs unless you specifically mention it as an argument. If you want to get it back, the hash will be recorded in the reflog or you could just copy the hash down somewhere and use the checkout -B command to put it back if you decide you need to.
If you don't want to resolve the conflict again, then don't reset the branch pointer, just merge again:
$ git checkout TASK-123-b
$ git merge TASK-123

And remove the old branch:
$ git branch -d TASK-123


A: For explanation purpose, assume that your commits are identified like this:
    master -a---c-----f-----h ...
             \         \
  TASK-123    b---d-e   \
                         \   
TASK-123-b                g---i ...


TL;DR


*

*Rebase, remove the merge commit (commit g), and edit the commit before the merge (commit f).

*Instead of doing git commit --amend on f, do a git merge e --no-commit.

*Checkout all files from commit g using git checkout g -- ..

*Commit and continue the rebasing process.

Detailed Answer
If your commit tree can be represented like this:
First, rebase using the commit hash second before the merge commit (the merge commit is g, so the commit hash will be used is the <commit-c-sha>)
$ git rebase --interactive <commit-c-sha>

This will generate a todo list like this:
pick <commit-f-sha>  <commit-f-message>   -----> change this to edit
pick <commit-g-sha>  <commit-g-message>   -----> remove this line
pick <commit-i-sha>  <commit-i-message>
...

So your todo list will be like:
edit <commit-f-sha>  <commit-f-message>
pick <commit-i-sha>  <commit-i-message>
...

Second, create a merge with no commit.
$ git merge <commit-e-sha> --no-commit

Here, we don't want to actually edit the commit f. Instead, we prepare a commit for commit g replacement.
This gives us a merge commit format and the flexibility to do some works on the merge commit (such as: modify files, modify commit properties, etc).
Third, we checked out all files from commit g to current index without moving the HEAD.
$ git checkout <commit-g-sha> -- .

This makes sure that the files will be committed are all the same with the files in commit g.
Fourth, persist the change and continue the rebasing process. For example:
$ git commit
$ git rebase --continue

You can add any commit options (but don't add --amend) or replace it with git commit-tree command.
After this, commit g will have two parents and all of the commits after g are following as well.
    master -a---c-----f-----h ...
             \         \
  TASK-123    b---d-e   \
                     \   \   
TASK-123-b            \---g---i ... and all of the following commits


Notes 1: Specify timestamp
When you make a commit, git by default set the commit date using the current time. If you want to specify the timestamp, you can check on GIT_AUTHOR_DATE & GIT_COMMITTER_DATE variables and the --date  option
ref: https://git-scm.com/docs/git-commit#_date_formats

Notes 2: Commit-Tree (not tried yet)
If you want a more flexible way to specify the commit parent(s), you can do a checkout and create the commit using the commit-tree command instead of the merge -> checkout -> commit pattern.
