git topics integrate
Merges an existing, "reasonably" stable topic branch named to the develop branch for testing & integration.
The merge is done with the --no-ff
flag, ensuring that a commit is always
created to record the fact that this topic was integrated. When the topic
branch gets deleted, you'll still be able to recover its history from this
merge commit.
Note that the topic branch will NOT be deleted here, in case issues are found
while testing the code on develop. If there are issues, you should make
further commits on the topic branch and git topics integrate
it again.
If develop is tracking a remote branch, git topics integrate
makes an
effort to ensure your local branch is up to date first. This avoids conflicts
if you later push upstream. This is done with a git fetch
of the
corresponding remote branch. If the local branch is behind, the topic will not
be merged. If the fetch itself fails, the topic will still be merged, but there
will be a warning. That way, transient issues like internet connection problems
won't get in the way of your development.
Essentially, this command is equivalent to
$ git checkout <develop>
$ git pull
$ git merge --no-ff <topic>
except that it only does a git fetch
, not a full git pull
, and only if
there's a remote tracking branch. If a git merge
from the upstream develop
is required, this command will stop short of actually merging the topic.
The same sort of git fetch
sanity check is run against the topic branch
itself, in case there were any remote changes.
Aside from the sanity checks beforehand, git topics integrate
is really just
equivalent to git merge --no-ff
. Specifically, there are no further actions
that the command performs after doing the merge. So in the event of a merge
conflict (or any other condition that causes git merge
to exit non-zero), you
may continue to resolve it the same way as if you'd simply used git merge
.
You could even use git merge --abort
.
It's worth noting that minor merge conflicts are a normal part of the workflow. A common mistake is to think your topic branch MUST merge 100% cleanly into develop or master. This leads people to one of two "solutions" to preempt merge conflicts:
-
Merge an upstream branch (develop or master) into the topic branch. This is frowned upon, especially if done habitually for no real reason (as noted in gitworkflows(7)). You still get the same merge conflicts as if you'd just merged the topic to the upstream. But then, instead of having a single, independent history of the topic, you get a rat's nest of changes from the upstream branch. For example, say you merged develop into your topic, then decided the topic was finished. If you were to merge the topic back to master, suddenly master would contain all of develop's changes!
-
Rebase the topic branch onto the latest master (rebasing on top of develop is just wrong, since topics should be based on master). This probably won't help with merge conflicts on develop in the first place, and at any rate rebasing should always be treated with caution. If your topic's history is still completely local, by all means rebase away to make your history cleaner. But if you've already pushed your topic publicly (e.g., using
git topics review
), rewriting history may cause more headaches than it's worth.
The "real" solution is generally to resolve merge conflicts as they happen,
instead of trying to preempt them. As long as you're making the fixes already,
you might as well record those in the merge commit itself: it's part of the
history too. It's the most relevant place to record conflict resolutions (be
sure to explain them in the commit message!), and you're guaranteed a merge
commit via --no-ff
regardless, which means the branch's history remains
intact.
As always, evaluate your needs on a case by case basis. There's no one-size-fits-all solution:
-
Typically, you want topics to be independent from each other, just to make things easier to manage. But if topic A actually depends on topic B, the order in which they're merged into master or develop becomes important. You might smooth out this ordering issue by first merging B into A, which guarantees that B's changes (at least at the time of the merge) are included in A. Then you need only merge A into master or develop, which will automatically pull in B's changes due to that first merge. This can make your history quite tangled, though. As of yet, git-topics has no builtin commands to handle this case: if you know your workflow is complex enough to require inter-topic merges, you probably know how to do that with regular git commands already.
-
Evil merges involve not just a simple textual conflict, but rather a more "semantic" one (e.g., someone has changed the name of a variable you depend on). One way to preempt such issues is to play with a throwaway branch before integrating your topic, which you could do with
git topics reintegrate --onto throwaway
. See git-topics-reintegrate(1). -
Maybe in some narrow case merging the upstream to your topic is actually appropriate.
-
It could be that rewriting commits (even public ones) is ultimately the way to go. Sometimes this is called a "reroll": to just write the feature over again with a cleaner patch set and/or history.
-
Of course, you could always make additional commits to your topic before merging to preempt some bad conflicts.
-
In certain situations, you just need to copy over a certain commit with
git cherry-pick
. This should be infrequent with proper branch management, though. -
etc
Use your best judgement.
git-topics(1), git-merge(1), git-checkout(1), git-fetch(1), git-pull(1)