git help in Windows command prompt - windows

The git help command on Windows (msysgit distribution) spawns web browser each time I run it. I tried git help -m which reports "No manual entry for ..." and git help -i which says "info: Terminal type 'msys' is not smart enough to run Info." The same happens in bash under Cygwin.
Is there any sensible way to get light-weight help in cmd terminal?

It works for particular commands: git <command> -h
Edit, thanks to #the-happy-hippo
But it shows only a brief description, not the full one, as git help <command> or git <command> --help gives on Windows.

git <verb> -h shows a command usage in the same terminal window.
On the other hand, git <verb> --help and git help <verb> open a browser.

Update for Git 2.x (June 2017, Git 2.13.1)
You still don't have man:
> git -c help.format=man help add
warning: failed to exec 'man': No such file or directory
fatal: no man viewer handled the request
Same for git <verb> --help.
git <verb> -h does not print the man page, only the short usage section (nothing to do with man)
With Git 2.34 (Q4 2021), when git cmd -h shows more than one line of usage text (e.g. the cmd subcommand may take sub-sub-command), parse-options API learned to align these lines, even across i18n/l10n.
See commit 4631cfc (21 Sep 2021), and commit 84122ec, commit 78a5091, commit 5d70198 (13 Sep 2021) by Ævar Arnfjörð Bjarmason (avar).
(Merged by Junio C Hamano -- gitster -- in commit d7bc852, 13 Oct 2021)
parse-options: properly align continued usage output
Signed-off-by: Ævar Arnfjörð Bjarmason
Some commands such as "git stash"(man) emit continued options output with e.g. git stash -h, because usage_with_options_internal() prefixes with its own whitespace the resulting output wasn't properly aligned.
Let's account for the added whitespace, which properly aligns the output.
The "git stash" command has usage output with a N_() translation that legitimately stretches across multiple lines;
N_("git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n"
" [-u|--include-untracked] [-a|--all] [-m|--message <message>]\n"
[...]
We'd like to have that output aligned with the length of the initial "git stash" output, but since usage_with_options_internal() adds its own whitespace prefixing we fell short, before this change we'd emit:
$ git stash -h
usage: git stash list [<options>]
or: git stash show [<options>] [<stash>]
[...]
or: git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]
[-u|--include-untracked] [-a|--all] [-m|--message <message>]
[...]
Now we'll properly emit aligned output.
I.e.
the last four lines above will instead be (a whitespace-only change to the above):
[...]
or: git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]
[-u|--include-untracked] [-a|--all] [-m|--message <message>]
[...]
This change is relatively more complex since I've accounted for making it future-proof for RTL translation support.
Later in usage_with_options_internal() we have some existing padding code dating back to d7a38c5 ("parse-options: be able to generate usages automatically", 2007-10-15, Git v1.5.4-rc0 -- merge) which isn't RTL-safe, but that code would be easy to fix.
Let's not introduce new RTL translation problems here.
Original answer (2014)
No, even though an alternative, based on a 'cat' of the htlp txt files, is suggested in "how do I get git to show command-line help in windows?".
There man.<tool>.cmd config introduced in 2008, allows to set a custom command, but msys shell isn't shipped with man.exe.

World's most overengineered workaround for this problem: use WSL
(that is, unless you already are a WSL user, in which case it's merely an ordinary workaround)
Install one of the linux distros via Windows Store
Go in and ensure it has the git package installed
From the Windows command line, bash -c 'git help fetch' etc.
Here's an alias for that last one:
[alias]
hep = "!f() { $SYSTEMROOT/System32/bash -c \"git help $1\"; }; f"
(And no you can't override git built-ins, but you can make a shell command to intercept and reroute help.)

Related

Git and Vim - Formatted wrong with git diff, but correct with git commit --amend

I am using Ubuntu for Windows.
Vim and git work fine when calling git commit --amend, but calling git diff or git log results in improperly formatted output. Can anyone please explain when the output is not formatted correctly like when calling git commit --amend?
I'm using zsh with git aliases, which is why it says I called gc! and not git commit --amend, etc.
The stuff you're seeing—the [32m, [m, and so on—is the result of partly, but not completely, stripping out colorization codes. Git is printing ESC [ (optional digits) m so as to tell your terminal emulator / display window to change colors, backgrounds, and so on. The pager you're using is for some reason removing the ESC but leaving the rest in.
To find out which pager you're using, use:
git var GIT_PAGER
To correct its behavior ... well, that depends on which pager you're using. :-)

Git get worktree for every branch in seperate folders - Bash

I need to write a bash script that copies our repository branches onto our local linux web server every hour.
We have a git remote repository (gitolite) with branches named "master" "testing" "feature-featurename" "hotfix-number"
each one of these branches is supposed to have its worktree copied to /var/www/html/branchname
First of all: How do I get different worktrees copied into different folders?
Second: How can I automate this process if the "feature-" and "hotfix-" branches constantly change names?
This has nothing to do with a git hook, this is supposed to be a script running on a different server which is triggered by a cron job.
Horrible few-liner:
mkdir -p /var/www/html
git clone --bare user#git-server:/your-repo.git && cd your-repo.git
git for-each-ref --format='%(refname)' refs/heads/ | grep 'branch-pattern' | while read branchRef; do
branchName=${branchRef#refs/heads/}
git archive --format=tar --prefix="$branchName/" "$branchRef" | tar -C/var/www/html -x
done
Let's break it down:
Make sure the target directory exists. Probably not necessary for you.
mkdir -p /var/www/html
Clone the git repository and enter the directory
git clone --bare user#git-server:/your-repo.git
List branches. This would be run from a cloned directory. Note that git branch is not used, as that can have surprising outputs when used in scripts.
git for-each-ref --format='%(refname)' refs/heads/
Filter for the branches you want. In your case the pattern would probably be something like grep -E "(master)|(testing)|(feature-.*)" etc.
grep 'branch-pattern'
The while statement reads each branch name and assigns it to the branch variable
Create a branchName variable that is the name of the branch excluding the ref prefix. Note that this is bash-specific.
git archive creates a tar archive of the selected branch, prefixing all entries with the branch name. The archive is sent to standard output
git archive --format=tar --prefix="$branch/" "$branch"
Immediately extract the archive to its target location
tar -C/var/www/html -x
How do I get different worktrees copied into different folders?
That is done with git worktree, as illustrated in Mark Adelsberger's answer.
That answer ends with:
You also could use git worktree list --porcelain instead of searching for worktree directories directly - and that may be preferable in odd cases like (again) namespaced branches.
With Git 2.36 (Q2 2022, see at the end):
git worktree list --porcelain -z
Actually, you should, especially with Git 2.31 (Q1 2021): git worktree list(man) now annotates worktrees as prunable, shows locked and prunable attributes in --porcelain mode, and gained a --verbose option.
See commit 076b444, commit 9b19a58, commit 862c723, commit 47409e7 (27 Jan 2021), and commit eb36135, commit fc0c7d5, commit a29a8b7 (19 Jan 2021) by Rafael Silva (raffs).
(Merged by Junio C Hamano -- gitster -- in commit 02fb216, 10 Feb 2021)
worktree: teach list verbose mode
Helped-by: Eric Sunshine
Signed-off-by: Rafael Silva
Reviewed-by: Eric Sunshine
"git worktree list"(man) annotates each worktree according to its state such as prunable or locked, however it is not immediately obvious why these worktrees are being annotated.
For prunable worktrees a reason is available that is returned by should_prune_worktree() and for locked worktrees a reason might be available provided by the user via lock command.
Let's teach "git worktree list" a --verbose mode that outputs the reason why the worktrees are being annotated.
The reason is a text that can take virtually any size and appending the text on the default columned format will make it difficult to extend the command with other annotations and not fit nicely on the screen.
In order to address this shortcoming the annotation is then moved to the next line indented followed by the reason If the reason is not available the annotation stays on the same line as the worktree itself.
The output of "git worktree list" with verbose becomes like so:
$ git worktree list --verbose
...
/path/to/locked-no-reason acb124 [branch-a] locked
/path/to/locked-with-reason acc125 [branch-b]
locked: worktree with a locked reason
/path/to/prunable-reason ace127 [branch-d]
prunable: gitdir file points to non-existent location
...
git worktree now includes in its man page:
For these annotations, a reason might also be available and this can be
seen using the verbose mode. The annotation is then moved to the next line
indented followed by the additional information.
$ git worktree list --verbose
/path/to/linked-worktree abcd1234 [master]
/path/to/locked-worktree-no-reason abcd5678 (detached HEAD) locked
/path/to/locked-worktree-with-reason 1234abcd (brancha)
locked: working tree path is mounted on a portable device
/path/to/prunable-worktree 5678abc1 (detached HEAD)
prunable: gitdir file points to non-existent location
Note that the annotation is moved to the next line if the additional
information is available, otherwise it stays on the same line as the
working tree itself.
And:
worktree: teach list to annotate prunable worktree
Helped-by: Eric Sunshine
Signed-off-by: Rafael Silva
Reviewed-by: Eric Sunshine
The "git worktree list"(man) command shows the absolute path to the worktree, the commit that is checked out, the name of the branch, and a "locked" annotation if the worktree is locked, however, it does not indicate whether the worktree is prunable.
The "prune" command will remove a worktree if it is prunable unless --dry-run option is specified.
This could lead to a worktree being removed without the user realizing before it is too late, in case the user forgets to pass --dry-run for instance.
If the "list" command shows which worktree is prunable, the user could verify before running "git worktree prune"(man) and hopefully prevents the working tree to be removed accidentally on the worse case scenario.
Let's teach "git worktree list" to show when a worktree is a prunable candidate for both default and porcelain format.
In the default format a "prunable" text is appended:
$ git worktree list
/path/to/main aba123 [main]
/path/to/linked 123abc [branch-a]
/path/to/prunable ace127 (detached HEAD) prunable
In the --porcelain format a prunable label is added followed by its reason:
$ git worktree list --porcelain
...
worktree /path/to/prunable
HEAD abc1234abc1234abc1234abc1234abc1234abc12
detached
prunable gitdir file points to non-existent location
...
git worktree now includes in its man page:
branch currently checked out (or "detached HEAD" if none), "locked" if
the worktree is locked, "prunable" if the worktree can be pruned by prune
command.
git worktree now includes in its man page:
The command also shows annotations for each working tree, according to its state.
These annotations are:
locked, if the working tree is locked.
prunable, if the working tree can be pruned via git worktree prune.
$ git worktree list
/path/to/linked-worktree abcd1234 [master]
/path/to/locked-worktreee acbd5678 (brancha) locked
/path/to/prunable-worktree 5678abc (detached HEAD) prunable
Before Git 2.36 (Q2 2022), "git worktree list --porcelain"(man) did not c-quote pathnames and lock reasons with unsafe bytes correctly, which is worked around by introducing NUL terminated output format with "-z".
See commit d97eb30 (31 Mar 2022) by Phillip Wood (phillipwood).
(Merged by Junio C Hamano -- gitster -- in commit 7c6d8ee, 04 Apr 2022)
worktree: add -z option for list subcommand
Signed-off-by: Phillip Wood
Add a -z option to be used in conjunction with --porcelain that gives NUL-terminated output.
As 'worktree list --porcelain' does not quote worktree paths this enables it to handle worktree paths that contain newlines.
git worktree now includes in its man page:
It is recommended to combine this with -z.
See below for details.
-z
Terminate each line with a NUL rather than a newline when
--porcelain is specified with list.
This makes it possible
to parse the output when a worktree path contains a newline
character.
git worktree now includes in its man page:
The porcelain format has a line per attribute.
If -z is given then the lines
are terminated with NUL rather than a newline.
So first you need a list of branches. For scripting purposes, the command best used for this is for-each-ref. Assuming you just want the local branch names, use something like
git for-each-ref refs/heads/* |cut -d\/ -f3
As an aside, a couple things in the above command assume that you don't use branches in "namespaces". If you use branch names like qa/feature-1 - containing / - then that changes a few things. The above command simply becomes
git for-each-ref refs/heads |cut -d\/ -f3-
but the bigger issue is you probably have to think more about how branch names should map to directory names. So for now I'll proceed with the assumption that branch names won't contain /.
You need to process each branch, so
git for-each-ref refs/heads/* |cut -d\/ -f3 |while read branch; do
# ... will process each branch here
done
Now you can use git worktree to streamline the individual checkouts. (Note that this should be much more efficient that using archive to copy the whole commit content for every branch, then invoking tar to undo the work you didn't want archive to do in the first place.)
To make sure all required work trees are defined
git for-each-ref refs/heads/* |cut -d\/ -f3 |while read branch; do
if [ ! -d .git/worktrees/$branch ]; then
git worktree add /var/www/html/$branch $branch
fi
done
Now one thing about this is that when the branches are moved (i.e. when pushes are received), it puts the work trees "out of sync" so that you appear to have staged the "undoing" of every change the push did. (The protections for the default work tree don't seem to apply.)
But that seems in line with your requirements; the alternative would be to have the directories updated as pushes come in, which you reject in your description of the problem. So your script should, in that case, sync the worktree to the new changes by "un-undoing" them
git for-each-ref refs/heads/* |cut -d\/ -f3 |while read branch; do
if [ ! -d .git/worktrees/$branch ]; then
git worktree add /var/www/html/$branch $branch
fi
git reset --hard HEAD
done
Of course sometimes branches go away; if you don't want stale worktree metadata you can add a
git worktree prune
You also could use git worktree list --porcelain instead of searching for worktree directories directly - and that may be preferable in odd cases like (again) namespaced branches.

Git checkout by date gives error on Windows

I want to checkout from git and using commands from this SO-link. I am not sure what I am doing wrong here.
I have tried following commands.
git checkout `git rev-list -n 1 --before="2015-3-3 13:37:00" master`
git checkout `git rev-list 1 --before="2015-3-3 13:37:00" master`
git checkout `git rev-list -1 --before="2015-3-3 13:37:00" master`
and get the following error.
C:\Users\junaid\Documents\GitHub\bucardo [master]> git checkout `git rev-list -n 1 --before="2015-3-3 13:37:00" master`
error: unknown switch `n'
usage: git checkout [options] <branch>
or: git checkout [options] [<branch>] -- <file>...
-q, --quiet suppress progress reporting
-b <branch> create and checkout a new branch
-B <branch> create/reset and checkout a branch
-l create reflog for new branch
--detach detach the HEAD at named commit
-t, --track set upstream info for new branch
--orphan <new branch>
new unparented branch
-2, --ours checkout our version for unmerged files
-3, --theirs checkout their version for unmerged files
-f, --force force checkout (throw away local modifications)
-m, --merge perform a 3-way merge with the new branch
--overwrite-ignore update ignored files (default)
--conflict <style> conflict style (merge or diff3)
-p, --patch select hunks interactively
--ignore-skip-worktree-bits
do not limit pathspecs to sparse entries only
But following command works but I think, it can go back to 90 days only.
C:\Users\junaid\Documents\GitHub\bucardo [master]> git checkout 'master#{2015-3-27 18:30:00}'
warning: Log for 'master' only goes back to Thu, 17 Mar 2015 18:08:03 -0500.
Note: checking out 'master#{2015-07-27 18:30:00}'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b new_branch_name
HEAD is now at cb4f95a... Start the cleanup of delete_rows()
C:\Users\junaid\Documents\GitHub\bucardo [(cb4f95a...)]>
In Bash (and many other Unixy shells) backticks are used for command substitution, e.g. see this description from The Linux Documentation Project:
Command substitution allows the output of a command to replace the command itself. Command substitution occurs when a command is enclosed like this:
$(command)
or like this using backticks:
`command`
Bash performs the expansion by executing COMMAND and replacing the command substitution with the standard output of the command, with any trailing newlines deleted. Embedded newlines are not deleted, but they may be removed during word splitting.
franky ~> echo `date`
Thu Feb 6 10:06:20 CET 2003
I don't think that cmd.exe supports real command substitution at all. It certainly doesn't treat backticks this way.
There are some workarounds that you can try, e.g. using for /f or temporary files, but these are awkward to use.
Depending on how you installed Git you might have access to a Bash shell on Windows that should work the way you want.
If you have access to PowerShell it looks like the $(...) syntax should work, which is also supported on Bash. posh-git has a good reputation as an environment for Git on PowerShell, though I've never used it personally.

How does one disable Git's HTML help (on Windows)?

I installed Github for Windows which comes with the Git command line client, and whenever I forget a switch or something and want to use --help, instead of dumping to the console it's launching a browser. Is there a way to ask Git to dump the help to the console (as it does in most Unixen by default) instead of launching a browser?
In windows
git <command> -h
will write help to the terminal output
git <command> --help
will pop up a browser window
This is a frail workaround, but if you just want a quick usage summary, feed the git sub-command of your choice a deliberately bad option name. I tried "--halp". For example:
$ git stash --halp
error: unknown option for 'stash save': --halp
To provide a message, use git stash save -- '--halp'
usage: git core\git-stash list [<options>]
or: git core\git-stash show [<stash>]
or: git core\git-stash drop [-q|--quiet] [<stash>]
or: git core\git-stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]
or: git core\git-stash branch <branchname> [<stash>]
or: git core\git-stash [save [--patch] [-k|--[no-]keep-index] [-q|--quiet]
[-u|--include-untracked] [-a|--all] [<message>]]
or: git core\git-stash clear
I can't say for sure that "halp" will always be rejected, but it seems to get the job done. Hopefully it'll never get interpreted as a usable parameter. This is probably better than random typing, for example, since you might randomly type in correct input.
For Linux systems you could set this with git config --global help.format <web|man|info>. Unfortunately the man pages are not part of the Git for Windows bundle so only 'web' works.

Is it possible to find the difference between two arbitrary text files using Git?

These files are not necessarily version controlled.
I'm using Git and Git GUI on Windows XP.
You'll need to use the --no-index option unless one or both of the files are outside of a Git repository:
git diff --no-index path/to/file.txt path/to/other/file.txt
You can also use git difftool with the same arguments to invoke your GUI tool.
Yes, git diff works on two unversioned paths, both files and directories (recursive diff). I don't think you can do this from the GUI; you'll need to use the command line.
If you want GUI, I suggest installing KDiff3 instead. It can also be used by Git as a merge tool than if you set diff.tool = kdiff3, diff.guitool = kdiff3 and difftool.kdiff3.path = path-to-kdiff3.exe
You can do that not only with git diff (with git diff --no-index -- file1 file2), but now (Git 2.22, Q2 2019) again with git difftool too!
It was not possible for the past two years.
"git difftool" can now run outside a repository.
See commit 20de316, commit 1a85b49, commit 1dcda05 (14 Mar 2019) by Johannes Schindelin (dscho).
(Merged by Junio C Hamano -- gitster -- in commit b72e907, 25 Apr 2019)
difftool: allow running outside Git worktrees with --no-index
As far as this developer can tell, the conversion from a Perl script to
a built-in caused the regression in the difftool that it no longer runs
outside of a Git worktree (with --no-index, of course).
It is a bit embarrassing that it took over two years after retiring the
Perl version to discover this regression, but at least we now know, and
can do something, about it.
It fixes git-for-windows/git issue 2123.
In Git Bash you can just use diff file1 file2.
Using TortoiseGit, select both files, right click select TortoiseGit and click diff.

Resources