thenigan / git-diffall Goto Github PK
View Code? Open in Web Editor NEWScript to perform directory diffs using an external diff tool in Git
Script to perform directory diffs using an external diff tool in Git
NOTE: The functionality provided by git-diffall has been contributed to Git itself and can be accessed through the "git difftool --dir-diff" command in Git versions v1.7.11 and newer. ## Overview The git-diffall script provides a directory based diff mechanism for git. To determine what diff viewer is used, the script requires either the 'diff.tool' or 'merge.tool' configuration option to be set. This script is compatible with most common forms used to specify a range of revisions to diff: 1. git diffall: shows diff between working tree and staged changes 2. git diffall --cached [<commit>]: shows diff between staged changes and HEAD (or other named commit) 3. git diffall <commit>: shows diff between working tree and named commit 4. git diffall <commit> <commit>: show diff between two named commits 5. git diffall <commit>..<commit>: same as above 6. git diffall <commit>...<commit>: show the changes on the branch containing and up to the second, starting at a common ancestor of both <commit> Note: all forms take an optional path limiter [-- <path>*] The '--extcmd=<command>' option allows the user to specify a custom command for viewing diffs. When given, configured defaults are ignored and the script runs $command $LOCAL $REMOTE. Additionally, $BASE is set in the environment. ## Installation Copy the `git-diffall` script to the directory where your `git` is installed. `$ cd <directory with git-diffall>` `$ cp git-diffall $(git --exec-path)` ## Setup The difftool and mergetool selected for use with `git-diffall` must be one that has a mergetool plugin in your `git` installation. The plugin is a simple script that populates the command-line arguments of the difftool/mergetool using the correct values from `git`. Plugins exist for a variety of tools already and can be found in `$(git --exec-path)/mergetools`. If your favorite tool is missing, you can add it by copying an existing plugin and modifying for your tool. The config commands follow this pattern: `$ git config --global diff.tool <one of the tools listed in $(git --exec-path)/mergetools>` `$ git config --global merge.tool <one of the tools listed in $(git --exec-path)/mergetools>` For example: `$ git config --global diff.tool kdiff3` `$ git config --global merge.tool kdiff3` ## Other Notes This script is based on an example provided by Thomas Rast on the Git list [1]: [1] http://thread.gmane.org/gmane.comp.version-control.git/124807 "git cola diff" [2] provides a graphical frontend for full-tree diffs similar in spirit to git-diffall. [2] https://github.com/git-cola/git-cola
When using DeltaWalker in OS X as my diff tool, git-diffall finishes and deletes all of the files before I've had a chance to review (probably because it launches in a separate window and the script just keeps going). As a workaround, I modified my local script to add a "read pause" after the "trap cleanup EXIT" line. This requires me to explicitly tell the script to continue on to deleting all of the temp files.
I'm not sure if something like this makes sense as a flag or as default behavior, but I imagine that a lot of people that try to use git-diffall get frustrated at first because of this issue.
Depending on the context:
On msysgit platform, the last command in the script doesn't work:
trap cleanup EXIT
Could it possible to solve it?
diff.tool or merge.tool is only necessary if using git-mergetool--lib to execute a merge tool. If you're running an external command this information is not required. I suggest changing the logic to test for presence of diff.tool or merge.tool only once args are parsed and --extcmd is not present.
If diff.tool is not present you get an annoying message from get_merge_tool(). This could be avoided if we only call this function if --extcmd is not present.
The joke's on me :/
I have tried:
git diffall -- path
git diffall -- path*
git diffall --path*
None of these options worked. Please advise if I missunderstood the command or if it is actually an issue.
When using the $ git diffall and you disregard changes and save the file, those changes are not saved.
See below for example:
mycpu$ git st
*On branch pushNot
*Changes not staged for commit:
no changes added to commit (use "git add" and/or "git commit -a")
mycpu$ git diffall // this is where DiffMerge pops up, where i then disregard changes and save and exit DiffMerge
mycpu$ git st
*On branch pushNot
*Changes not staged for commit:
no changes added to commit (use "git add" and/or "git commit -a")
mycpu$
The perl implementation chokes on line 126 with:
❯ git diffall
No such file or directory at /usr/lib/git-core/git-diffall--lib line 126.
I'm not fluent in perl. I've used some print statements and it seems to be trying to write to /tmp/git-diffall.5U5FV/left/bin/git-diffall
.
I'm simply trying diffall on my https://github.com/grota/rcfiles repo:
diff --git i/bin/git-diffall w/bin/git-diffall
index 0838b05..4046847 160000
--- i/bin/git-diffall
+++ w/bin/git-diffall
@@ -1 +1 @@
-Subproject commit 0838b05556b608ca82d613c0a0e01dab97ab1511
+Subproject commit 4046847990d89e13fa53b0e4bc14be8d3e8ef1f6
I might be doing something silly myself since I haven't been able to test git-diffall for a while.
This new issue has been opened in response to Giuseppe's comments in issue #21:
On Tue, Apr 3, 2012 at 2:21 PM, Giuseppe Rota wrote:
yes, it fixes the core issue. I still see 2 minor annoyances, though, due to the
fact the we use the --raw option.
- Referring to the use case above, the
private
submodule (which is -dirty) does
not get detected as modified since both "temp" files contain
Subproject commit f53be889043c6ca7885f98b17247a470c00273bb
, while the
right one should probably also contain the same plus '-dirty'.- The temp file for the bin/git-diffall submodule contains
Subproject commit 0000000000000000000000000000000000000000
I don't see an easy way out of this, git-diff --submodule doesn't seem to help eithier,
so this is just FYI.
For inclusion in package managers (such as Homebrew), it would be nice to have a tagged stable revision, rather than relying on HEAD.
In version 1.7.7.4 (looks to be a change between 1.7.6 and 1.7.7, the setup_tool call in /opt/local/libexec/git-core/git-mergetool--lib returns a non-zero value if there isn't a file in $(git --exec-path)/mergetools/ which has the name of the diff tool that I've specified in my .gitconfig. setup_tool is called by run_merge_tool, which is called by git-diffall.
The setup_tool code is below:
# Load the default definitions
. "$mergetools/defaults"
if ! test -f "$mergetools/$tool"
then
return 1
fi
What this appears to be doing is causing run_merge_tool to stop before it finishes executing and actually runs the diff/merge command. Changing that return value to 0 makes everything work as expected.
It seems like weird behavior for setup_tool to return 1 for this use case anyway as mergetools/defaults loads exactly what I need for deltawalker to work (because I've defined the cmd in my .gitconfig).
Anyway, I'm going to change the function to return '0' for now, but I obviously don't want to be leaving edited core git files around, so if you could shed some light on this, I'd appreciate it.
What would it take to use the working tree directory directly instead of a temporary directory whenever the working tree matches what would end up in the temporary directory? Some diff tools -- Beyond Compare, Guiffy -- allow editing the files under comparison, and it would be really nice to edit the affected files as I'm diffing.
How do you even use it?
An example would be nice!
To allow integration with GNU/Linux distributions please attach a decent copyleft license (i.e. GPL-3+) or permissive one.
License statement is required these days. Thank you.
With the current argument parsing "git-diffall -- foo bar baz" essentially means limit to "foo bar baz", instead of foo, or bar or baz. Removing quotes around "$paths" in git invocations fixes the problem.
Several users have reported issues integrating their favorite diff tool with this script.
So far, in all cases, it has been due to a failure to configure their GUI diff tool with a -wait
or no-fork
option which will prevent the tool from starting a new process.
It would be helpful to post instructions for integrating with common diff tools including:
How about patching the script, so that if you're comparing against the working directory, it would copy back all the changes to the working directory. Or, set temporary files as symbolic links (problem with mingw version though...).
This fits the workflow of "diff against revision, pick what you want from it if you see that it fits".
Using the perl implementation works fine with something like-x meld
but I have been using this git alias to invoke a vimdiff based tool:
diffall --extcmd "vim -f '+next' '+execute \"DirDiff\" argv(0) argv(1)'"
now invoking git dd
gives me:
fatal: ambiguous argument ''+next'': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions
diff --raw --no-abbrev -z --copy-back -f '+next' '+execute "DirDiff" argv(0) argv(1)': command returned error: 128```
Sadly Perl is not in my arsenal so I can't be of much help.
In this case the script aborts with:
fatal: Path '/something/somefile' exists on disk, but not in 'some-tag'
Just as a workaround I changed line 140 from:
git show "$left":"$name" > "$tmp"/a/"$name"
to:
git show "$left":"$name" > "$tmp"/a/"$name" || true
which gives me the diff for all other files without aborting. But this is not a proper solution of course as it ignores all errors and does not check any other command where I guess it can also happen.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.