I'm on Windows 10, using Git command line and have WinMerge set up as my difftool.
I have a repository with several submodules. When running "git diff" and "git difftool" within the main repo, it correctly uses WinMerge to analyze the files. When I navigate to a submodule and run "git diff" or "git difftool" it does nothing.
Here's my .gitconfig:
[diff]
tool = winmerge
[difftool "winmerge"]
cmd = winmergeu -e \"$LOCAL\" \"$REMOTE\"
This is what I get when I git diff in the parent repo:
$ git diff
diff --git a/content/themes/baseline-theme b/content/themes/baseline-theme
--- a/content/themes/baseline-theme
+++ b/content/themes/baseline-theme
## -1 +1 ##
-Subproject commit 30901f86ba56be092f1ed5c7095204abe7f64b27
+Subproject commit 30901f86ba56be092f1ed5c7095204abe7f64b27-dirty
I get no output when I run the same command in the submodule.
How can I resolve this?
You would need at least Git 2.11 for git diff --submodule=diff to work.
And 2.14 for it to work in submodules of submodules (ie recursively).
See my answer "see diff of commit on submodule".
Related
I want to make a automated test system. Users upload or change their script, when they push file to git, system will get the commit action, and know the commit id, like 3c6a88d527ccaefabf98d00f47f04789f01e2830, and boot a docker to run changed script.
at first, git clone all file to a directory, after that get what files is changed by order:
git diff-tree --no-commit-id --name-only -r <id>
After a long time, there will be a lot of scripts in the repository, I don't want to pull all the scripts to the local directory every time I test.Is there any command to pull only part of the files I want?
# Shows commit logs and diff output
git whatchanged <sha-1>
Using diff-tree (as you figured out)
# Fetch out changes (no need to checkout branches)
git fetch --all --prune
# Now print out the changes
git diff-tree --no-commit-id --name-only -r <id>
I currently have a git project with the structure:
z.txt
foo/a.txt
foo/b.txt
using bash how can I identify after running $ git pull that either a.txt and/or b.txt (i.e anything under the foo directory) have been altered?
A. If you already pulled
git diff
You can use git diff and specifically:
git diff commit1..commit2 --name-only; or
git diff commit1..commit2 --name-status
The following descriptions are from the doco.
--name-only
Show only names of changed files.
--name-status
Show only names and status of changed files. See the description of the --diff-filter option on what the status letters mean.
git pull tells you the commit ids it merges/fast-forwards:
/mnt/c/git/repo666 (develop)>git pull
Updating f86907f7a..a708dcfe8
In this case the command would be:
git diff f86907f7a..a708dcfe8 --name-status
git log
To see differences per commit you could use git log with --name-only or --name-status.
B. Before a pull
If you haven't pulled and you want a peek at the potential changes you can git fetch the branch (not pull) and compare the local copy of the remote branch your current branch.
/mnt/c/git/repo666(develop)>git fetch // not git pull
(...)
/mnt/c/git/repo666(develop)>git status
On branch develop
Your branch is behind 'origin/develop' by 3 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
nothing to commit, working tree clean
/mnt/c/git/Platform (develop)>git diff develop origin/develop --name-status
(Please note I used git diff branch origin/branch and not git diff origin/branch so that is shown in the desired order i.e. if the file was added in origin/develop we want to see it as added not deleted.)
Note on git pull output
Please note that the output of git pull contains added and renamed files twice
Fast-forward
...
src/Folder1/Services/File1.cs | 30 +
src/Folder1/Services/File2.cs | 7 +
...
src/Folder1/ViewModels/XViewModel.cs | 8 +-
...
src/{Abc.Common/Services => Abc/Contracts/Area1}/Area1File1.cs | 7 +-
...
89 files changed, 7254 insertions(+), 4897 deletions(-)
create mode 100644 src/Folder1/Services/File1.cs
create mode 100644 src/Folder1/Services/File2.cs
...
rename src/{Abc.Common/Services => Abc/Contracts/Area1}/Area1File1.cs (83%)
...
We can get closer than what #tymtam suggests, if you're willing to do things before you run git pull.
Get the SHA for your current head and save it:
sha="$(git rev-parse HEAD)"
Next, run the pull:
git pull
Finally, compare foo on your new HEAD to what you had before:
git diff --stat $sha -- foo
Note, if you have uncommitted changes, those will be included in what git diff reports, so you can always run git stash before your diff command to hide them, and then git stash pop to get them back.
So I'm running:
git diff <rev-hash-1> <rev-hash-2> -- ./proj/MAP.csv
and all I get is blank output.
Per the documentation I'm using the following command format:
git diff [<options>] <commit> <commit> [--] [<path>…]
the directory above ./proj is the root of the local repo where .git lives.
I've also tried the same command with the following paths, but it still comes back blank:
.\proj\MAP.csv
.\proj\MAP.csv .\proj\MAP.csv
./proj/MAP.csv ./proj/MAP.csv
./proj/MAP.csv
proj/MAP.csv
proj/MAP.csvproj/MAP.csv``
Is there anything else you need to make this work in the following version of git bash for Windows?
$ git --version
git version 2.19.0.windows.1
Git version: 2.14.2.2
Whenever I run git diff on a repository I am greeted with the response No tags file. I have tried running the command on multiple repositories, multiple consoles (Cmd, PowerShell, MINGW64, Visual Studio Command Prompt) and all have the same response.
Strangely, the git log command also fails. Many other commands work, however, such as git status, git pull, etc. It seems to be only log and diff.
I have uninstalled Git entirely and reinstalled. Restarted my system. Tried referencing the git.exe directly (which yields the exact same response). Nothing is working and I have not seen this error anywhere else. I compared my user configs with those of a colleague and they are identical.
Some portion of the command executes properly, because if I supply two commit hashes, and I intentionally break one, the response I receive is:
It seems like another program may be hijacking the git diff command. I believe this because I'm not sure "No tags file" is even a possible Git response. Not sure what else it would be.
To make things even more confusing- my ultimate goal is to run the git diff within the context of an msbuild and it DOES EXECUTE CORRECTLY. Now, I could be satisfied with this, but I need to modify the diff command slightly, and running a full build each time is not productive, nor easy to troubleshoot. There is a task within the build script that runs an Exec command and it has no issues performing the diff. I'm also able to execute a Diff Against Current within SourceTree, which to the best of my knowledge, runs a git diff behind the scenes.
Any help would be very much appreciated.
:: Edits ::
Various commands:
git diff HEAD~1 HEAD
git diff master~1 master
git diff <commit-hash-1> <commit-hash-2>
git log HEAD~1..HEAD
git log master~1..master
git log <commit-hash-1>..<commit-hash-2>
Output:
Every one of the commands above returns the same No tags file response, in all of my repos.
Cat Head:
cd .git
cat HEAD
ls -R refs
Output:
New Repo:
mkdir testrepo
cd testrepo
git init
echo "file1" > file1.txt
git add .
git commit -m "initial commit of file1.txt"
echo "Hi there!" > file2.txt
git add .
git commit -m "added file2.txt"
git log
git diff HEAD~1 HEAD
Output:
git config -e:
git config --global -e:
::Edits 2::
I uninstalled all of my diffing/source control tools (SourceTree, Git, SVN, WinMerge, KDiff). Installed the portable version of Git. Opened CMD to a repo, put in full path to the git.exe portable and it still returned the No tags file response.
I also reviewed all of my path variables for: git, vim, ming, mintty and anything else that seemed suspect, but didn't find any.
I have restarted after performing all steps, and yet the problem persists.
::Edits 3::
I have a different user on my laptop, switched to that user and the git diff works properly, so clearly there is something with my main user that is conflicting. Will continue to look into my User directory for issues.
Here are the steps I'd take in this situation:
Try the following and check the response:
git diff HEAD~1 HEAD
git diff master~1 master
git diff <commit-hash-1> <commit-hash-2>
Try the same with log:
git log HEAD~1..HEAD
git log master~1..master
git log <commit-hash-1>..<commit-hash-2>
I'm actually guessing that your refs are messed up, which means that the direct hashes might work, but the HEAD and/or master one may not.
Look into the .git/refs folder
From the main repo folder:
cd .git
cat HEAD
ls -R refs
Hopefully, HEAD is pointing to a branch, and if master is checked out, cat HEAD output should look like:
ref: refs/heads/master
Then, the ls -R refs, should show a heads folder, with files for each of your local branches (i.e. master and possibly others). You also likely have refs/remotes and refs/tags directories.
If any of these things are radically different or missing, that could be your issue...
Since you have reinstalled git, create a brand new repo and try the same commands:
mkdir testrepo
cd testrepo
git init
echo "file1" > file1.txt
git add .
git commit -m "initial commit of file1.txt"
echo "Hi there!" > file2.txt
git add .
git commit -m "added file2.txt"
git log
git diff HEAD~1 HEAD
If this last one works, then git is likely working okay, but some tool you have is messing things up.
Post your config from git config -e and git config --global -e - maybe we can see something?
When googling for the "No tags file" message, the first results I get all talk about vi.
I do not understand why git would try to execute vi when running git diff or git log, could it be that your system is configured to use vi as a pager ?
# some possible places which could influence that :
echo $PAGER
echo $GIT_PAGER
git config --get core.pager
When digging in the documentation for less, I found that less can use a ctags file, to spot "the file that contains this tag".
So you can also look at the list of variables that influence the behavior of less :
# from bash :
# env will list all the defined environment variables
env
# the ones that impact 'less' should contain "LESS" in their names :
env | grep LESS
So, I've been learning a bit more about git submodules, and everywhere that I read tells me that I end up with a detached HEAD after I add my submodule. This makes sense as I want my superproject to know specifically which commit should be used. However, it isn't what I am seeing in practice (on Mac OS X).
Consider the following sequence of commands that create a quick repo (called sub) with a single file in it, and then adds that as a submodule to another repo called blah.
/tmp> git version
git version 1.7.12.4 (Apple Git-37)
/tmp> git init sub
Initialized empty Git repository in /private/tmp/sub/.git/
/tmp> cd sub
/tmp/sub> touch a.txt
/tmp/sub> git add a.txt
/tmp/sub> git commit -m "add a file"
[master (root-commit) c527790] .
0 files changed
create mode 100644 a.txt
/tmp/sub> cd ..
/tmp> git init blah
Initialized empty Git repository in /private/tmp/blah/.git/
/tmp> cd blah
/tmp/blah> git submodule add /tmp/sub sub
Cloning into 'sub'...
done.
/tmp/blah> cd sub
/tmp/blah/sub> git status
# On branch master
nothing to commit (working directory clean)
Why is the submodule on the master branch? I would have expected it to say that it is not on a branch. A bit more digging suggests that git is referencing the correct commit hash, but is somehow on the master branch, instead of a detached HEAD.
/tmp/blah/sub> cd ../../sub
/tmp/sub> git reflog
97b97b3 HEAD#{0}: commit (initial): add a file
/tmp/sub> cd ../blah
/tmp/blah> git submodule status
97b97b349cfae8da490c2cad3b3f4fc3af6a53c7 sub (heads/master)
What am I missing? Thanks a lot.
Running this command:
git submodule add /tmp/sub sub
Results in a normal clone operation, so you end up on the HEAD of the master branch. However, if you examine the resulting commit, you'll see that git records the explicit commit hash in your repository.
From inside your blah repository:
$ git commit -m 'added submodule'
[master (root-commit) 13e36eb] added submodule
2 files changed, 4 insertions(+)
create mode 100644 .gitmodules
create mode 160000 sub
$ git log --oneline
13e36eb added submodule
$ git cat-file -p 13e36eb
tree 5d205c2e2ce63d8087b3b6644e3ac183cd49c644
author Lars <lars#> 1363184265 -0400
committer Lars <lars#> 1363184265 -0400
added submodule
$ git cat-file -p 5d205c2e2ce63d8087b3b6644e3ac183cd49c644
100644 blob 30c9a7559a85f36bcedaabb8bdfaf43363966b85 .gitmodules
160000 commit 2122e5378b7940afae8e49ad9179c815c7711610 sub
That last line (160000 commit ...) shows the commit hash that git has recorded for your submodule.
If you were now to clone your repository with the submodule...
cd /tmp
git clone --recursive blah cloned-blah
You would find that sub is now not on a branch, because instead of a normal clone operation this checked out the explicit commit.