How to use vimdiff

Vim can be used as a diff and merge tool. While it cannot match the beauty and power of GUI programs like Meld, it is immensely useful to diff and merge over a SSH session.

  • Vim can be invoked in diff mode either using vim -d or as vimdiff. Just pass in the names of the files to compare:
$ vimdiff 1.cpp 2.cpp
$ vim -d 1.cpp 2.cpp 3.cpp
  • Vim in diff mode displays each file in its own window side-by-side showing the diff sections in colors. You can switch between the windows using the normal Vim commands. (I use Ctrl-W-W.) And when you scroll down all the windows scroll down with you because they are locked to each other.

  • To switch to and fro between diffs use the ]-c and [-c commands.

  • To put the diff the cursor is resting on to the next window use the command dp

  • To pull the diff from the next window use the command do

Tried with: Vim 7.4 and Ubuntu 16.04

Advertisements

Merge with squash in Git

Merge is a common operation in Git to merge the changes in another branch to the current branch.

Here is an example, where we checkout the master branch and merge a feature_branch to it:

$ git checkout master
$ git merge feature_branch
$ git commit
Before merge of feature_branch to master
Before merge of feature_branch to master
After merge of feature_branch to master
After merge of feature_branch to master

In the pictorial depictions above we can see that the two branches are actually merged together in the directed acyclic graph (DAG) with an edge. After this, the git log for master will show all the commits that are in feature_branch too in addition to the commits in master.

There might be cases where you do not want to actually merge the two branches. Maybe you just want a single commit on master that has all the changes that would have been merged from feature_branch. Note that this is different from git rebase since that replays all the multiple commits of feature_branch on master.

The answer to this is git merge --squash. This command effectively changes the files such that they would be after a git merge. However, there would be no link between master and feature_branch after this commit is committed.

To merge with squash in the above scenario:

$ git checkout master
$ git merge --squash feature_branch
$ git commit

When you commit you will see that Git inserts a default commit message that says Squashed commit of the following and lists all the commits from feature_branch that are squashed into this commit. You can delete this commit message and create your own of course.

After merge --squash of feature_branch to master
After merge –squash of feature_branch to master

The pictorial depiction of this operation above shows that there is no link between the two branches after this merge. When you do git log no one can see the multiple commits of feature_branch. You can even safely delete feature_branch if you want to after this operation.

Tried with: Git 2.9.0 and Ubuntu 16.04

How to resolve Git conflict with binary files

If a binary file in a Git repository has changed between your branch and the branch you try to merge, you will get a merge conflict. Since it is a binary file, you typically cannot use a 3-way merge tool to fix this. In most cases, you know that either you want to keep your version of the file or the one you are merging from.

To commit your file:

$ git checkout --ours -- somepath/foobar.bin
$ git add somepath/foobar.bin
$ git commit

To commit the file from the other branch:

$ git checkout --theirs -- somepath/foobar.bin
$ git add somepath/foobar.bin
$ git commit

Tried with: Git 2.4.1 and Ubuntu 14.04