How can I make `git diff` as fine-grained as StackExchange diff? - diff

Is there a diff tool which can highlight single character edits as such, and not just show the old and new version of the whole line (i.e. the kind of diff StackExchange shows you for edits to a post)?
I'd prefer one I could use on the Linux command line as diff in git.

You can try, from git diff:
git diff --color-words=.
Which is equivalent to --word-diff=color plus (if a regex was specified) --word-diff-regex=<regex>.
That would transform this git diff:
into this one:
Images are from the section "Produce more useful diffs" of the article "30 Git CLI options you should know about" written in Sept. 2014 by Christophe Porteneuve.

Related

How to compare files between two svn revisions in VS code?

I know you can code --diff file1 file2 to use the compare tool in VS code, but is it possible to compare two different svn revisions of a file?
I'd like to be able to combine svn diff -r 111:222 file1 with code --diff ....
Now svn diff would only give me a diff file so it's not enough to compare the whole files in VS code.
I guess I could checkout both revisions of that file and code --diff those, but ideally I'd like to do this without the checkout since I'd do this frequently.
I believe that the following command will help:
svn diff -r1000:1001 https://demo-server.visualsvn.com/asf/ --diff-cmd code -x "--wait --diff"
You may need to adjust the command line to your needs. Note that the URL is unnecessary if you run svn diff in a working copy. See the following pages for more information:
SVNBook | svn diff
SVNBook | Using External Differencing and Merge Tools
I've just tried the above command and it opens SVN diff in VSCode.
PS I see the following warning in the command-line output, but I'm unsure of its meaning:
Warning: 'L' is not in the list of known options, but still passed to
Electron/Chromium.

Eclipse eGit on Linux screwing line endings

Because of the changes in line endings, commits looks a lot bigger than they should be.
I have egit 4.6.1.201703071140
Before using egit, the command
git ls-files --eol
shows
i/mixed w/mixed attr/ somefile
then, after commit in Eclipse via git staging view, it is:
i/lf w/mixed attr/ somefile
Another example:
i/crlf w/crlf attr/ somefile2
becomes:
i/lf w/crlf attr/ somefile2
You can see egit is changing the first column to i/lf.
In GitHub you can use ?w=1 to dampen the noise, but how do I fix the problem itself?
git config
core.autocrlf=input
core.repositoryformatversion=0
core.filemode=true
core.logallrefupdates=true
remote.origin.url=https://github.com/plutext/docx4j.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
branch.master.rebase=false
According to https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration:
You can tell Git to convert CRLF to LF on commit but not the other way around by setting core.autocrlf to input.
You probably want to use false instead.

Merge/diff tool that can show authors (supports blame or annotate) in files under version control

When merging files it will be helpful (as for me) to show an author of each line. Is there any diff or merge tool supporting that?
The bundled gitk tool is not really a merge tool, but it shows conflicted lines with red and blue and "+"'s in front, and you can Rightclick->"Show origin of this line" on any of them, to go to the commit which introduced the line:
You can run your mergetool, or just a text editor with diffmarks in parallel
So what you really want is a tool that can easily identify your changes
relative to other's changes in a merge conflict, rather actually identify
the author of each line (which would be a mean to achieve that), right?
If I understood you correctly, I have some relatively good news: It
can be done with git + kdiff3. For merging you can just use git mergetool
(which you can configure to use kdiff3). But it is not supported natively
if you get a merge conflict when doing interactive rebase, so for that
some manual scripting is required.
Instead of making up my own simple merge conflict example, I will use
http://www.gitguys.com/topics/merging-with-a-conflict-conflicts-and-resolutions/
as an basis. Follow that page to git merge test. From after the merge
command I diverge a bit from that example by running different commands
(but basically doing the same job). I'll do all the manuall steps first.
So we have a merge conflict and git has inserted content from both
contributing sources into the file in this <<<<<<<...>>>>>>> format,
which I really do not like at all and never consider even looking at it.
Instead I use my favourite merge tool, kdiff3.
First we need to find which versions that are involved.
$ git ls-files -u
100644 b0ed415d15862ac5582b51e4de65528e86934cd2 1 README
100644 56300e3ac4e4521c3500618a301bb2ab2d6a52f5 2 README
100644 9585db7d9c2d9ca05075f67a878f2554886d7b1a 3 README
$
Basted that information we can perform a three way merge:
$ git cat-file blob b0ed415d15862ac5582b51e4de65528e86934cd2 > v1
$ git cat-file blob 56300e3ac4e4521c3500618a301bb2ab2d6a52f5 > v2
$ git cat-file blob 9585db7d9c2d9ca05075f67a878f2554886d7b1a > v3
$ kdiff3 -o merge_result v1 v2 v3 &
[2] 18394
$
Which gives the following view where you can select from which ancestor
you want to merge from.
Afterwords (if you are satisfied with the merge result)
you need to
$ rm v1 v2 v3
$ mv merge_result README
$ git add README
All the manual steps above are done automatically with git mergetool.
So why showing all that then? Well, because if you get a corresponding
conflict during git rebase -i, then it has to be done that way (before running git rebase --continue).
In this small example there is only one conflict
line, so it does not show the more typical case where a lot of lines
are automatically resolved, leaving you to just manually resolve the
ones that was not done automatically.
A more real life example might look more like the following:
Notice that in the merge result you now clearly see the origin of the C lines that
were automatically resolved. I think this is sort of what you were asking for when asking for getting the author for each line, right?
That information is completely absent in the <<<<<<<...>>>>>>> text (and it is difficult/impossible to spot that you should update the printed string in the hello function).
I cannot recommend kdiff3 highly enough. Using a graphical merge tool like that compared to some lines from both sources mixed inline in the file is like using an excavator versus a spade.
No. And, I think, never will be - when we merge, we think about content, not authorship

CVS: command-line diff on a remote CVS server between two HEAD revs

My CVS-fu is not very strong anymore (after years of SVN'ing and now Mercurial'ing). I'm trying to do a diff between two revisions of the HEAD branch (everything is in the HEAD anyway).
I received an IDE already set up to use a :pserver:myname#cvsserver:port/cvs/project CVS. I'm on Windows XP. I do not want to use the IDE (the goal here is to learn CVS a bit more).
Apparently I cannot login using SSH to the CVS server.
How can I run a remote CVS diff between two HEAD revs using the command line?
P.S: I am new here, mod me up so I can comment etc. :)
Is there any particular reason you want to learn more CVS after experiencing the wonders of SVN and Mercurial? In this industry, the opportunity cost of learning an outdated and difficult-to-use technology is that you forego the opportunity to learn something new and potentially more useful.
You may of course have a good reason, such as company requirements or other things outside of your control :(
With that said, this resource essentially serves as a CVS guidebook and a reference to many CVS command line tools. It looks like you can see differences between revisions on the HEAD, but only one file at a time.
http://kuparinen.org/martti/comp/cvs/cvs.html#8
[Show changes between two versions]
# cvs diff -u -r 1.42 -r 1.43 filename
# cvs diff -u -r BEFORE-XYZ -r HEAD [filename]

Is there a way to get CVS to not produce merge conflicts on keyword substitutions like $Id: $

We use CVS currently and develop new features on a branch before merging to trunk. Occasionally we get merge conflicts caused by the CVS keyword substitution. So when reviewing the conflict file we see something like this
<<<<<<< collect_logs.conf
# CVS $Id: collect_logs.conf,v 1.6 2010/02/03 16:43:11 peterw Exp $
=======
# CVS $Id: collect_logs.conf,v 1.13 2010-05-07 17:14:43 peterw Exp $
>>>>>>> 1.13
And that will be the only conflict in the file.
I have done a little bit of investigating and as you probably notice there is a slight difference in the formatting of the date in the entry. This is due to different cvs version being used over different platforms (one on Solaris, the other on Linux) I believe that is what's triggering the conflict.
The workaround is to simply do a fresh checkout of the project and then to do the cvs update from there. As all the keywords are generated in the same format it is happy to merge.
My Question is can you command cvs to cope better with merging on the keyword substitutions. Or is it simply better to avoid it with fresh checkouts like I have?
Thanks
Peter
You would use update -kk ... as per the CVS documentation on Merging and keywords(section 5.10).
The k attached to the -k (keyword substitution mode) causes CVS to just output the keyword and not the value of the keyword. So in theory your multiple date formats shouldn't be a problem. I haven't tested this theory though.