I am using 'git log' on the windows7 command line and it is very slow.
I tried: Git/Bash is extremely slow in Windows 7 x64
but this did not help. How can i speed things up?
Check if the issue persists with the latest Git for Windows Git 2.20.1
And Git 2.21 (Q1 2019) will improve the speed for a particular form of git log:
git log -G<regex> looked for a hunk in the "git log -p" patch output that contained a string that matches the given pattern.
Optimize this code to ignore binary files, which by default will not show any hunk that would match any pattern (unless textconv or the --text option is in effect, that is).
See commit e0e7cb8 (14 Dec 2018) by Thomas Braun (t-b).
(Merged by Junio C Hamano -- gitster -- in commit ecdc7cb, 14 Jan 2019)
log -G: ignore binary files
The -G<regex> option of log looks for the differences whose patch text contains added/removed lines that match regex.
Currently -G looks also into patches of binary files (which according to LibXDiff) is binary as well.
This has a couple of issues:
It makes the pickaxe search slow.
In a proprietary repository of the author with only ~5500 commits and a total .git size of ~300MB:
searching takes ~13 seconds
$time git log -Gwave > /dev/null
real 0m13,241s
user 0m12,596s
sys 0m0,644s
whereas when we ignore binary files with this patch it takes ~4s:
$time ~/devel/git/git log -Gwave > /dev/null
real 0m3,713s
user 0m3,608s
sys 0m0,105s
which is a speedup of more than fourfold.
The internally used algorithm for generating patch text is based on
xdiff and its states in LibXDiff:
The output format of the binary patch file is proprietary
(and binary) and it is basically a collection of copy and insert
commands [..]
which means that the current format could change once the internal algorithm is changed as the format is not standardized.
In addition the git binary patch format used for preparing patches for git apply is different from the xdiff format as can be seen by comparing.
git log -p -a
commit 6e95bf4bafccf14650d02ab57f3affe669be10cf
Author: A U Thor <author#example.com>
Date: Thu Apr 7 15:14:13 2005 -0700
modify binary file
diff --git a/data.bin b/data.bin
index f414c84..edfeb6f 100644
--- a/data.bin
+++ b/data.bin
## -1,2 +1,4 ##
a
a^#A
+a
+a^#A
with git log --binary
commit 6e95bf4bafccf14650d02ab57f3affe669be10cf
Author: A U Thor <author#example.com>
Date: Thu Apr 7 15:14:13 2005 -0700
modify binary file
diff --git a/data.bin b/data.bin
index f414c84bd3aa25fa07836bb1fb73db784635e24b..edfeb6f501[..]
GIT binary patch
literal 12
QcmYe~N#Pgn0zx1O01)N^ZvX%Q
literal 6
NcmYe~N#Pgn0ssWg0XP5v
which seems unexpected.
To resolve these issues this patch makes -G<regex> ignore binary files by default.
Textconv filters are supported and also -a/--text for getting the old and broken behaviour back.
The -S<block of text> option of log looks for differences that changes the number of occurrences of the specified block of text (i.e. addition/deletion) in a file. As we want to keep the current behaviour, add a test to ensure it stays that way.
Related
When troubleshooting git issues of users, I keep running into people not noticing error/warning messages from git, and then burning their fingers. Is there any way to colorify errors and warnings git outputs?
Since I didn't find a suitable way to color error messages, my solution is to add an additional warning when git returns an error code (!=0).
To do it, add this to your ~/.bashrc or ~/.bash_profile
# Wrap git. On errors, print an additional line in red.
git(){
command git "$#"
local exitCode=$?
if [ $exitCode -ne 0 ]; then
printf "\033[0;31mERROR: git exited with code $exitCode\033[0m\n"
return $exitCode
fi
}
Here is the result:
Note that coloring stderr in red does not work very well because git logs many things in stderr, not only errors. And some errors are output in standard output.
With Git 2.18 (Q2 2018), you now have a better documentation of the settings to colorize push errors/hints.
See commit 79f62e7 (21 Apr 2018) by Johannes Schindelin (dscho).
(Merged by Johannes Schindelin -- dscho -- in commit 79f62e7, 24 Apr 2018)
push: colorize errors
This is an attempt to resolve an issue I experience with people that are
new to Git -- especially colleagues in a team setting -- where they miss
that their push to a remote location failed because the failure and
success both return a block of white text.
An example is if I push something to a remote repository and then a
colleague attempts to push to the same remote repository and the push
fails because it requires them to pull first, but they don't notice
because a success and failure both return a block of white text. They
then continue about their business, thinking it has been successfully
pushed.
This patch colorizes the errors and hints (in red and yellow,
respectively) so whenever there is a failure when pushing to a remote
repository that fails, it is more noticeable.
With Git 2.19 (Q3 2018), The sideband code learned to optionally paint selected keywords at the beginning of incoming lines on the receiving end.
See commit bf1a11f (07 Aug 2018) by Han-Wen Nienhuys (hanwen).
Helped-by: Jonathan Nieder (artagnon).
(Merged by Junio C Hamano -- gitster -- in commit d280170, 20 Aug 2018)
sideband: highlight keywords in remote sideband output
The colorization is controlled with the config setting "color.remote".
Supported keywords are "error", "warning", "hint" and "success".
They are highlighted if they appear at the start of the line, which is
common in error messages, eg.
ERROR: commit is missing Change-Id
The Git push process itself prints lots of non-actionable messages (eg. bandwidth statistics, object counters for different phases of the process).
This obscures actionable error messages that servers may send back.
Highlighting keywords in the sideband draws more attention to those messages.
The background for this change is that Gerrit does server-side processing to create or update code reviews, and actionable error messages (eg. missing Change-Id) must be communicated back to the user during the push.
User research has shown that new users have trouble seeing these messages.
The highlighting is done on the client rather than server side, so servers don't have to grow capabilities to understand terminal escape codes and terminal state.
It also consistent with the current state where Git is control of the local display (eg. prefixing messages with "remote: ").
The highlighting can be configured using color.remote.<KEYWORD> configuration settings.
Since the keys are matched case insensitively, we match the keywords case insensitively too.
Finally, this solution is backwards compatible: many servers already
prefix their messages with "error", and they will benefit from this
change without requiring a server update.
By contrast, a server-side solution would likely require plumbing the TERM variable through the git protocol, so it would require changes to both server and client.
Note: Use Git 2.21 (Q1 2019): Lines that begin with a certain keyword that come over the wire, as well as lines that consist only of one of these keywords, ought to be painted in color for easier eyeballing, but the latter was broken ever since the feature was introduced in 2.19, which has been corrected.
See commit 1f67290 (03 Dec 2018) by Stefan Beller (stefanbeller).
(Merged by Junio C Hamano -- gitster -- in commit 20b3bc1, 14 Jan 2019)
sideband: color lines with keyword only
When bf1a11f (sideband: highlight keywords in remote sideband output,
2018-08-07) was introduced, it was carefully considered which strings would be highlighted.
However 59a255a (sideband: do not read beyond the end of input, 2018-08-18) brought in a regression that the original did not test for.
A line containing only the keyword and nothing else ("SUCCESS") should still be colored.
There is no git buit-in way to do that. Git just prints errors to STDERR and doesn’t care about the fatality of the error or anything. What you can do is color STDERR red. How to do this has been asked on on ServerFault: https://serverfault.com/questions/59262/bash-print-stderr-in-red-color
There are three basic options:
Run your command like this:
*git-command* 2> >(while read line; do echo -e "\e[01;31m$line\e[0m" >&2; done)
Use a wrapper script (See ServeFault for those), and run commands like
mywrapper *git-command*
Install stderred. This will allow you to make the effect permanent, without modifying your command line. Not sure whether this will work on windows, though.
You can use the color config section of git.
For more information and examples see http://git-scm.com/book/en/Customizing-Git-Git-Configuration#Colors-in-Git or the second part of http://blog.philippmetzler.com/?p=15
example: (add to your .gitconfig)
[color]
interactive = always
[color "interactive"]
error = red bold
When using "svn log -v" directories that were added through a merge from a different branch show a merge reference, and all files contained within are omitted. Is there an easy way to display those files other than running the log command for the reference revision in the source branch?
IE:
$ svn commit -m "Added example dir"
Adding dir
Adding dir/a
Adding dir/b
Transmitting file data ..done
Committing transaction...
Committed revision 16.
$ svn update
Updating '.':
At revision 16.
$ svn log -v -l 1 .
------------------------------------------------------------------------
r16 | U3FS | 2018-01-08 17:21:22 -0600 (Mon, 08 Jan 2018) | 1 line
Changed paths:
A /lab/branches/source/dir
A /lab/branches/source/dir/a
A /lab/branches/source/dir/b
Added example dir
$ svn merge -c 16 ../source/ .
--- Merging r16 into '.':
A dir
A dir/a
A dir/b
--- Recording mergeinfo for merge of r16 into '.':
U .
$ svn commit -m "Merged example dir"
Sending .
Adding dir
Committing transaction...
Committed revision 17.
$ svn update
Updating '.':
At revision 17.
$ svn log -v -l 1 .
------------------------------------------------------------------------
r17 | U3FS | 2018-01-08 17:23:41 -0600 (Mon, 08 Jan 2018) | 1 line
Changed paths:
M /lab/branches/target
A /lab/branches/target/dir (from /lab/branches/source/dir:16)
Merged example dir
------------------------------------------------------------------------
I'd like to be able to see the addition of 'a' and 'b' under 'dir/' for r17 in the 'target' branch. I'm thinking I'm gonna need some bash magic to combine the logs, but trying to avoid writing something much more complex than it needs to be. All ideas welcome.
If I'm understanding what you're asking correctly, svn log -g should do what I think you're attempting to do, which is to look at the merge history.
svn log -vg if you'd like it verbose (I prefer this one).
The command git diff "??/??/15 - 12:34" "??/??/?? - 03:21" throws an error. It seems that : is the culprit.
The client that handles git for me, didn't throw and error with the colon in the commit name, but git Bash for Windows won't let me get access to the commit using the command line options. I've tried ':' or ":" or \: and none of those options worked.
How would someone use a colon on the command line or how would someone escape the colon character?
* EDIT *
Here's a copy of the output from git log --oneline
9c34cd9 git merge
f1195c7 09/04/2015 - 15:05
db38edb 09/03/15 - 17:28
c20dea6 09/02/15 - 19:43
e33cd9c 08/28/15 - 00:12
48692a9 08/26/15 - 16:02
8072375 08/25/15 - 19:58
c6babf3 08/25/15 - 12:12
ff6afbf 08/14/15 - 19:43
a0ccc60 08/08/15 - 13:43
9b446ae 08/04/15 - 16:11
34a7dfe 08/02/15 - 21:09
f6005ba 07/31/15 - 16:12
18dc958 07/31/15 - 16:11
3d4c7fb 07/31/15 - 13:48
c6c9ef9 07/25/15 - 22:42
9fd46df 07/25/15 - 15:23
78fa4ed 07/20/15 - 12:27
af399b7 07/16/15 - 17:00
33fbd24 07/14/15 - 17:46
458bb5e 07/14/15 - 12:32
418a92d 07-13-15 - EOD
72b1408 07/13/15 - 17:43
a6bc32f Merge https://github.com/halcyonsystems/amelia
ec27a81 new file: assets/css/main.css
new file: assets/im2ff9bc3 Initial commit
From the help page (git help diff):
NAME
git-diff - Show changes between commits, commit and working tree, etc
SYNOPSIS
git diff [options] [<commit>] [--] [<path>...]
git diff [options] --cached [<commit>] [--] [<path>...]
git diff [options] <commit> <commit> [--] [<path>...]
git diff [options] <blob> <blob>
git diff [options] [--no-index] [--] <path> <path>
So you can specify two different path options. If those are timestamps you have to get them into the right syntax. See git help revisions:
<refname>#{<date>}, e.g. master#{yesterday}, HEAD#{5 minutes ago}
A ref followed by the suffix # with a date specification enclosed in a brace pair (e.g. {yesterday}, {1 month 2 weeks 3 days 1 hour 1 second ago} or {1979-02-26
18:30:00}) specifies the value of the ref at a prior point in time. This suffix may only be used immediately following a ref name and the ref must have an existing log
($GIT_DIR/logs/<ref>). Note that this looks up the state of your local ref at a given time; e.g., what was in your local master branch last week. If you want to look at
commits made during certain times, see --since and --until.
This works well for a single file as refname.
If you want to really diff all the changes in your full repo between two times, see this question and this question
Update based on the update of the question and clarifications in the comments:
As the dates appear in the first line of the commit message, you first have to search for the matching date (=commit message) in your repository to determine the unique checksum that identifies the respective commit just as Wumpus explained in the comments:
git log --oneline --grep='07/25/15 - 22:42'
This should work in your case. In the general case where the date or the search string cannot be found in the first line of the commit message use:
git log --grep='07/25/15 - 22:42'
If you have multiple branches and don't know on which branch the respective commit is to be found, add the --all switch.
On the output you will find the checksum, e.g. 3d4c7fb. This is the unique identifier which you can then feed into git diff. Note that the full checksum is actually a bit longer, but abbreviations are fine as long as they are unambiguous. Usually the first four to six digits are sufficient, depending on the amount of commits done in the past.
As Wumpus already said: This is awful. Do not add the commit date to the log message. It is redundant and therefore meaningless: git already maintains two dates for each commit: The author date and the commit date. For the first commit of a changeset these two are identical. During operations that integrate one commit onto a different branch (and generating a new commit checksum), the commit date represents the timestamp of the operation while the author date remains the same old. As I explained above you can refer to a file at a certain timestamp with filename#{timestamp}. See git help revisions to learn about the details of what you can do with the syntax. It's neat and quite flexible.
I am trying to make a diff between local and remote git branches using the following command:
git diff --ignore-space-at-eol -b -w --minimal remotes/branch/master > diff.patch
Everything is ok except I see in the patch file output such as
diff --git a/src/game/AccountMgr.cpp b/src/game/AccountMgr.cpp
index a271c8a..6f363c6 100644
--- a/src/game/AccountMgr.cpp
+++ b/src/game/AccountMgr.cpp
diff --git a/src/game/AccountMgr.h b/src/game/AccountMgr.h
index d406496..405fa32 100644
--- a/src/game/AccountMgr.h
+++ b/src/game/AccountMgr.h
...
Seems there are no changes in such files. How can I remove such files from the diff?
Note that the same git diff --ignore-space-at-eol can have the reverse bug: show no change where there is one:
See commit 044fb19, commit a5229cc (09 Jul 2016) by Johannes Schindelin (dscho).
(Merged by Junio C Hamano -- gitster -- in commit f2cfb8f, 25 Jul 2016)
git version
git version 2.9.2.windows.1
printf "a\nb\nc\n" >pre
printf "a\nbX\nc\n" >post
git diff --no-index --patience --ignore-space-at-eol pre post
(empty!?)
Git 2.10+ (Q3 2016) will fix that:
diff: fix a double off-by-one with --ignore-space-at-eol
When comparing two lines, ignoring any whitespace at the end, we first try to match as many bytes as possible and break out of the loop only upon mismatch, to let the remainder be handled by the code shared with the other whitespace-ignoring code paths.
When comparing the bytes, however, we incremented the counters always,
even if the bytes did not match.
And because we fall through to the space-at-eol handling at that point, it is as if that mismatch never happened.
See "xdiff/xutils.c"
Seems a bug in an outdated msys git version. Update to the latest fixed the problem.
I mean that I need to identify a set of applied patches by some number or a string to quickly check if I have the same code version as the other people without any synchronizations.
Is there some built-in darcs solution for this?
There's no short identifier for this - it's one of the downsides of the cheap cherry-picking darcs gives you. You can get a long identifier by first running darcs optimize --reorder and then looking at the output of darcs changes --context - but two repos with the same contents might list things in the context in different order, so it's still not perfect. You could sort the output and compare those.
So overall
darcs optimize --reorder
darcs changes --context | sort | md5sum
would give you a reasonable approximation of a version identifier.
The darcs optimize --reorder step isn't absolutely necessary, it's just possible that without it you'll get different results when the repos actually contain the same set of patches.
You can also use darcs pull and darcs push to see whether there are any patches not synchronized.
$ darcs pull --dry-run ; darcs push --dry-run
Would pull from "/home/masse/temp/2013/01/09/tests/project"...
Would pull the following changes:
Wed Jan 9 16:39:50 EET 2013 mats.rauhala#iki.fi
* Canonical order for colors
Making no changes: this is a dry run.
Would push to "/home/masse/temp/2013/01/09/tests/project"...
No recorded local changes to push!