Merge branch 'devel' of git://repo.or.cz/git/mingw/4msysgit into devel

This commit is contained in:
Johannes Schindelin
2011-07-09 17:48:50 +02:00
267 changed files with 10888 additions and 3323 deletions

4
.gitignore vendored
View File

@@ -127,7 +127,10 @@
/git-rm
/git-send-email
/git-send-pack
/git-sh-i18n
/git-sh-i18n--envsubst
/git-sh-setup
/git-sh-i18n
/git-shell
/git-shortlog
/git-show
@@ -160,6 +163,7 @@
/gitk-git/gitk-wish
/gitweb/GITWEB-BUILD-OPTIONS
/gitweb/gitweb.cgi
/gitweb/static/gitweb.js
/gitweb/static/gitweb.min.*
/test-chmtime
/test-ctype

View File

@@ -0,0 +1,47 @@
Git v1.7.5.1 Release Notes
==========================
Fixes since v1.7.5
------------------
* When an object "$tree:$path" does not exist, if $path does exist in the
subtree of $tree that corresponds to the subdirectory the user is in,
git now suggests using "$tree:./$path" in addition to the advice to use
the full path from the root of the working tree.
* The "--date=relative" output format used to say "X years, 12 months"
when it should have said "X+1 years".
* The smart-HTTP transfer was broken in 1.7.5 when the client needs
to issue a small POST (which uses content-length) and then a large
POST (which uses chunked) back to back.
* "git clean" used to fail on an empty directory that is not readable,
even though rmdir(2) could remove such a directory. Now we attempt it
as the last resort.
* The "--dirstat" option of "diff" family of commands used to totally
ignore a change that only rearranged lines within a file. Such a
change now counts as at least a minimum but non zero change.
* The "--dirstat" option of "diff" family of commands used to use the
pathname in the original, instead of the pathname in the result,
when renames are involved.
* "git pack-object" did not take core.bigfilethreashold into account
(unlike fast-import); now it does.
* "git reflog" ignored options like "--format=.." on the command line.
* "git stash apply" used to refuse to work if there was any change in
the working tree, even when the change did not overlap with the change
the stash recorded.
* "git stash apply @{99999}" was not diagnosed as an error, even when you
did not have that many stash entries.
* An error message from "git send-email" to diagnose a broken SMTP
connection configuration lacked a space between "hello=<smtp-domain>"
and "port=<smtp-server-port>".
And other minor fixes and documentation updates.

View File

@@ -0,0 +1,57 @@
Git v1.7.5.2 Release Notes
==========================
The release notes to 1.7.5.1 forgot to mention:
* "git stash -p --no-keep-index" and "git stash --no-keep-index -p" now
mean the same thing.
* "git upload-pack" (hence "git push" over git native protocol) had a
subtle race condition that could lead to a deadlock.
Fixes since v1.7.5.1
--------------------
* "git add -p" did not work correctly when a hunk is split and then
one of them was given to the editor.
* "git add -u" did not resolve a conflict where our history deleted and
their history modified the same file, and the working tree resolved to
keep a file.
* "git cvsimport" did not know that CVSNT stores its password file in a
location different from the traditional CVS.
* "git diff-files" did not show the mode information from the working
tree side of an unmerged path correctly.
* "git diff -M --cached" used to use unmerged path as a possible rename
source candidate, which made no sense.
* The option name parser in "git fast-import" used prefix matches for
some options where it shouldn't, and accepted non-existent options,
e.g. "--relative-marksmith" or "--forceps".
* "git format-patch" did not quote RFC822 special characters in the
email address (e.g From: Junio C. Hamano <jch@example.com>, not
From: "Junio C. Hamano" <jch@example.com>).
* "git format-patch" when run with "--quiet" option used to produce a
nonsense result that consists of alternating empty output.
* In "git merge", per-branch branch.<name>.mergeoptions configuration
variables did not override the fallback default merge.<option>
configuration variables such as merge.ff, merge.log, etc.
* "git merge-one-file" did not honor GIT_WORK_TREE settings when
handling a "both sides added, differently" conflict.
* "git mergetool" did not handle conflicted submoudules gracefully.
* "git-p4" (in contrib) used a wrong base image while merge a file that
was added on both branches differently.
* "git rebase -i -p" failed to preserve the history when there is a
redundant merge created with the --no-ff option.
And other minor fixes and documentation updates.

View File

@@ -0,0 +1,32 @@
Git v1.7.5.3 Release Notes
==========================
Fixes since v1.7.5.2
--------------------
* The bash completion scripts should correctly work using zsh's bash
completion emulation layer now.
* Setting $(prefix) in config.mak did not affect where etc/gitconfig
file is read from, even though passing it from the command line of
$(MAKE) did.
* The logic to handle "&" (expand to UNIX username) in GECOS field
miscounted the length of the name it formatted.
* "git cherry-pick -s resolve" failed to cherry-pick a root commit.
* "git diff --word-diff" misbehaved when diff.suppress-blank-empty was
in effect.
* "git log --stdin path" with an input that has additional pathspec
used to corrupt memory.
* "git send-pack" (hence "git push") over smalt-HTTP protocol could
deadlock when the client side pack-object died early.
* Compressed tarball gitweb generates used to be made with the timestamp
of the tarball generation; this was bad because snapshot from the same
tree should result in a same tarball.
And other minor fixes and documentation updates.

View File

@@ -0,0 +1,21 @@
Git v1.7.5.4 Release Notes
==========================
Fixes since v1.7.5.3
--------------------
* The single-key mode of "git add -p" was easily fooled into thinking
that it was told to add everthing ('a') when up-arrow was pressed by
mistake.
* Setting a git command that uses custom configuration via "-c var=val"
as an alias caused a crash due to a realloc(3) failure.
* "git diff -C -C" used to disable the rename detection entirely when
there are too many copy candidate paths in the tree; now it falls
back to "-C" when doing so would keep the copy candidate paths
under the rename detection limit.
* "git rerere" did not diagnose a corrupt MERGE_RR file in some cases.
And other minor fixes and documentation updates.

View File

@@ -0,0 +1,134 @@
Git v1.7.6 Release Notes (draft)
========================
Updates since v1.7.5
--------------------
* Various git-svn updates.
* Updates the way content tags are handled in gitweb. Also adds
a UI to choose common timezone for displaying the dates.
* Similar to branch names, tagnames that begin with "-" are now
disallowed.
* Clean-up of the C part of i18n (but not l10n---please wait)
continues.
* The scripting part of the codebase is getting prepared for i18n/l10n.
* Pushing and pulling from a repository with large number of refs that
point to identical commits are optimized by not listing the same commit
during the common ancestor negotiation exchange with the other side.
* Adding a file larger than core.bigfilethreshold (defaults to 1/2 Gig)
using "git add" will send the contents straight to a packfile without
having to hold it and its compressed representation both at the same
time in memory.
* Processes spawned by "[alias] <name> = !process" in the configuration
can inspect GIT_PREFIX environment variable to learn where in the
working tree the original command was invoked.
* A magic pathspec ":/" tells a command that limits its operation to
the current directory when ran from a subdirectory to work on the
entire working tree. In general, ":/path/to/file" would be relative
to the root of the working tree hierarchy.
After "git reset --hard; edit Makefile; cd t/", "git add -u" would
be a no-op, but "git add -u :/" would add the updated contents of
the Makefile at the top level. If you want to name a path in the
current subdirectory whose unusual name begins with ":/", you can
name it by "./:/that/path" or by "\:/that/path".
* "git blame" learned "--abbrev[=<n>]" option to control the minimum
number of hexdigits shown for commit object names.
* "git blame" learned "--line-porcelain" that is less efficient but is
easier to parse.
* Aborting "git commit --interactive" discards updates to the index
made during the interctive session.
* "git commit" learned a "--patch" option to directly jump to the
per-hunk selection UI of the interactive mode.
* "git diff" and its family of commands learned --dirstat=0 to show
directories that contribute less than 0.1% of changes.
* "git diff" and its family of commands learned --dirstat=lines mode to
assess damage to the directory based on number of lines in the patch
output, not based on the similarity numbers.
* "git format-patch" learned "--quiet" option to suppress the output of
the names of generated files.
* "git format-patch" quotes people's names when it has RFC822 special
characters in it, e.g. "Junio C. Hamano" <jch@example.com>. Earlier
it was up to the user to do this when using its output.
* "git format-patch" can take an empty --subject-prefix now.
* "git log" and friends learned a new "--notes" option to replace the
"--show-notes" option. Unlike "--show-notes", "--notes=<ref>" does
not imply showing the default notes.
* They also learned a log.abbrevCommit configuration variable to augment
the --abbrev-commit command line option.
* "git ls-remote" learned "--exit-code" option to consider it a
different kind of error when no remote ref to be shown.
* "git merge" learned "-" as a short-hand for "the previous branch", just
like the way "git checkout -" works.
* "git merge" uses "merge.ff" configuration variable to decide to always
create a merge commit (i.e. --no-ff, aka merge.ff=no), refuse to create
a merge commit (i.e. --ff-only, aka merge.ff=only). Setting merge.ff=yes
(or not setting it at all) restores the default behaviour of allowing
fast-forward to happen when possible.
* p4-import (from contrib) learned a new option --preserve-user.
* "git read-tree -m" learned "--dry-run" option that reports if a merge
would fail without touching the index nor the working tree.
* "git rebase" that does not specify on top of which branch to rebase
the current branch now uses @{upstream} of the current branch.
* "git rebase" finished either normally or with --abort did not
update the reflog for HEAD to record the event to come back to
where it started from.
* "git remote add -t only-this-branch --mirror=fetch" is now allowed. Earlier
a fetch-mode mirror meant mirror everything, but now it only means refs are
not renamed.
* "git rev-list --count" used with "--cherry-mark" counts the cherry-picked
commits separately, producing more a useful output.
* "git submodule update" learned "--force" option to get rid of local
changes in submodules and replace them with the up-to-date version.
* "git status" and friends ignore .gitmodules file while the file is
still in a conflicted state during a merge, to avoid using information
that is not final and possibly corrupt with conflict markers.
Also contains various documentation updates and minor miscellaneous
changes.
Fixes since v1.7.5
------------------
Unless otherwise noted, all the fixes in 1.7.5.X maintenance track are
included in this release.
* "git config" used to choke with an insanely long line.
(merge ef/maint-strbuf-init later)
---
exec >/var/tmp/1
echo O=$(git describe master)
O=v1.7.5.3-365-g7eacc2b
git shortlog --no-merges ^maint ^$O master

View File

@@ -344,50 +344,20 @@ MUA specific hints
Some of patches I receive or pick up from the list share common
patterns of breakage. Please make sure your MUA is set up
properly not to corrupt whitespaces. Here are two common ones
I have seen:
properly not to corrupt whitespaces.
* Empty context lines that do not have _any_ whitespace.
See the DISCUSSION section of git-format-patch(1) for hints on
checking your patch by mailing it to yourself and applying with
git-am(1).
* Non empty context lines that have one extra whitespace at the
beginning.
One test you could do yourself if your MUA is set up correctly is:
* Send the patch to yourself, exactly the way you would, except
To: and Cc: lines, which would not contain the list and
maintainer address.
* Save that patch to a file in UNIX mailbox format. Call it say
a.patch.
* Try to apply to the tip of the "master" branch from the
git.git public repository:
$ git fetch http://kernel.org/pub/scm/git/git.git master:test-apply
$ git checkout test-apply
$ git reset --hard
$ git am a.patch
If it does not apply correctly, there can be various reasons.
* Your patch itself does not apply cleanly. That is _bad_ but
does not have much to do with your MUA. Please rebase the
patch appropriately.
* Your MUA corrupted your patch; "am" would complain that
the patch does not apply. Look at .git/rebase-apply/ subdirectory and
see what 'patch' file contains and check for the common
corruption patterns mentioned above.
* While you are at it, check what are in 'info' and
'final-commit' files as well. If what is in 'final-commit' is
not exactly what you would want to see in the commit log
message, it is very likely that your maintainer would end up
hand editing the log message when he applies your patch.
Things like "Hi, this is my first patch.\n", if you really
want to put in the patch e-mail, should come after the
three-dash line that signals the end of the commit message.
While you are at it, check the resulting commit log message from
a trial run of applying the patch. If what is in the resulting
commit is not exactly what you would want to see, it is very
likely that your maintainer would end up hand editing the log
message when he applies your patch. Things like "Hi, this is my
first patch.\n", if you really want to put in the patch e-mail,
should come after the three-dash line that signals the end of the
commit message.
Pine
@@ -443,89 +413,10 @@ that or Gentoo did it.) So you need to set the
it.
Thunderbird
-----------
Thunderbird, KMail, GMail
-------------------------
(A Large Angry SCM)
By default, Thunderbird will both wrap emails as well as flag them as
being 'format=flowed', both of which will make the resulting email unusable
by git.
Here are some hints on how to successfully submit patches inline using
Thunderbird.
There are two different approaches. One approach is to configure
Thunderbird to not mangle patches. The second approach is to use
an external editor to keep Thunderbird from mangling the patches.
Approach #1 (configuration):
This recipe is current as of Thunderbird 2.0.0.19. Three steps:
1. Configure your mail server composition as plain text
Edit...Account Settings...Composition & Addressing,
uncheck 'Compose Messages in HTML'.
2. Configure your general composition window to not wrap
Edit..Preferences..Composition, wrap plain text messages at 0
3. Disable the use of format=flowed
Edit..Preferences..Advanced..Config Editor. Search for:
mailnews.send_plaintext_flowed
toggle it to make sure it is set to 'false'.
After that is done, you should be able to compose email as you
otherwise would (cut + paste, git-format-patch | git-imap-send, etc),
and the patches should not be mangled.
Approach #2 (external editor):
This recipe appears to work with the current [*1*] Thunderbird from Suse.
The following Thunderbird extensions are needed:
AboutConfig 0.5
http://aboutconfig.mozdev.org/
External Editor 0.7.2
http://globs.org/articles.php?lng=en&pg=8
1) Prepare the patch as a text file using your method of choice.
2) Before opening a compose window, use Edit->Account Settings to
uncheck the "Compose messages in HTML format" setting in the
"Composition & Addressing" panel of the account to be used to send the
patch. [*2*]
3) In the main Thunderbird window, _before_ you open the compose window
for the patch, use Tools->about:config to set the following to the
indicated values:
mailnews.send_plaintext_flowed => false
mailnews.wraplength => 0
4) Open a compose window and click the external editor icon.
5) In the external editor window, read in the patch file and exit the
editor normally.
6) Back in the compose window: Add whatever other text you wish to the
message, complete the addressing and subject fields, and press send.
7) Optionally, undo the about:config/account settings changes made in
steps 2 & 3.
[Footnotes]
*1* Version 1.0 (20041207) from the MozillaThunderbird-1.0-5 rpm of Suse
9.3 professional updates.
*2* It may be possible to do this with about:config and the following
settings but I haven't tried, yet.
mail.html_compose => false
mail.identity.default.compose_html => false
mail.identity.id?.compose_html => false
(Lukas Sandström)
There is a script in contrib/thunderbird-patch-inline which can help
you include patches with Thunderbird in an easy way. To use it, do the
steps above and then use the script as the external editor.
See the MUA-SPECIFIC HINTS section of git-format-patch(1).
Gnus
----
@@ -540,71 +431,3 @@ characters (most notably in people's names), and also
whitespaces (fatal in patches). Running 'C-u g' to display the
message in raw form before using '|' to run the pipe can work
this problem around.
KMail
-----
This should help you to submit patches inline using KMail.
1) Prepare the patch as a text file.
2) Click on New Mail.
3) Go under "Options" in the Composer window and be sure that
"Word wrap" is not set.
4) Use Message -> Insert file... and insert the patch.
5) Back in the compose window: add whatever other text you wish to the
message, complete the addressing and subject fields, and press send.
Gmail
-----
GMail does not appear to have any way to turn off line wrapping in the web
interface, so this will mangle any emails that you send. You can however
use "git send-email" and send your patches through the GMail SMTP server, or
use any IMAP email client to connect to the google IMAP server and forward
the emails through that.
To use "git send-email" and send your patches through the GMail SMTP server,
edit ~/.gitconfig to specify your account settings:
[sendemail]
smtpencryption = tls
smtpserver = smtp.gmail.com
smtpuser = user@gmail.com
smtppass = p4ssw0rd
smtpserverport = 587
Once your commits are ready to be sent to the mailing list, run the
following commands:
$ git format-patch --cover-letter -M origin/master -o outgoing/
$ edit outgoing/0000-*
$ git send-email outgoing/*
To submit using the IMAP interface, first, edit your ~/.gitconfig to specify your
account settings:
[imap]
folder = "[Gmail]/Drafts"
host = imaps://imap.gmail.com
user = user@gmail.com
pass = p4ssw0rd
port = 993
sslverify = false
You might need to instead use: folder = "[Google Mail]/Drafts" if you get an error
that the "Folder doesn't exist".
Once your commits are ready to be sent to the mailing list, run the
following commands:
$ git format-patch --cover-letter -M --stdout origin/master | git imap-send
Just make sure to disable line wrapping in the email client (GMail web
interface will line wrap no matter what, so you need to use a real
IMAP client).

View File

@@ -52,6 +52,11 @@ of lines before or after the line given by <start>.
--porcelain::
Show in a format designed for machine consumption.
--line-porcelain::
Show the porcelain format, but output commit information for
each line, not just the first time a commit is referenced.
Implies --porcelain.
--incremental::
Show the result incrementally in a format designed for
machine consumption.

View File

@@ -593,6 +593,8 @@ it will be treated as a shell command. For example, defining
"gitk --all --not ORIG_HEAD". Note that shell commands will be
executed from the top-level directory of a repository, which may
not necessarily be the current directory.
'GIT_PREFIX' is set as returned by running 'git rev-parse --show-prefix'
from the original current directory. See linkgit:git-rev-parse[1].
am.keepcr::
If true, git-am will call git-mailsplit for patches in mbox format
@@ -712,9 +714,16 @@ second is the background. The position of the attribute, if any,
doesn't matter.
color.diff::
When set to `always`, always use colors in patch.
When false (or `never`), never. When set to `true` or `auto`, use
colors only when the output is to the terminal. Defaults to false.
Whether to use ANSI escape sequences to add color to patches.
If this is set to `always`, linkgit:git-diff[1],
linkgit:git-log[1], and linkgit:git-show[1] will use color
for all patches. If it is set to `true` or `auto`, those
commands will only use color when output is to the terminal.
Defaults to false.
+
This does not affect linkgit:git-format-patch[1] nor the
'git-diff-{asterisk}' plumbing commands. Can be overridden on the
command line with the `--color[=<when>]` option.
color.diff.<slot>::
Use customized color for diff colorization. `<slot>` specifies
@@ -800,11 +809,15 @@ color.status.<slot>::
color.branch.<slot>.
color.ui::
When set to `always`, always use colors in all git commands which
are capable of colored output. When false (or `never`), never. When
set to `true` or `auto`, use colors only when the output is to the
terminal. When more specific variables of color.* are set, they always
take precedence over this setting. Defaults to false.
This variable determines the default value for variables such
as `color.diff` and `color.grep` that control the use of color
per command family. Its scope will expand as more commands learn
configuration to set a default for the `--color` option. Set it
to `always` if you want all output not intended for machine
consumption to use color, to `true` or `auto` if you want such
output to use color when written to the terminal, or to `false` or
`never` if you prefer git commands not to use color unless enabled
explicitly with some other configuration or the `--color` option.
commit.status::
A boolean to enable/disable inclusion of status information in the
@@ -1302,9 +1315,16 @@ instaweb.port::
interactive.singlekey::
In interactive commands, allow the user to provide one-letter
input with a single key (i.e., without hitting enter).
Currently this is used only by the `\--patch` mode of
linkgit:git-add[1]. Note that this setting is silently
ignored if portable keystroke input is not available.
Currently this is used by the `\--patch` mode of
linkgit:git-add[1], linkgit:git-checkout[1], linkgit:git-commit[1],
linkgit:git-reset[1], and linkgit:git-stash[1]. Note that this
setting is silently ignored if portable keystroke input
is not available.
log.abbrevCommit::
If true, makes linkgit:git-log[1], linkgit:git-show[1], and
linkgit:git-whatchanged[1] assume `\--abbrev-commit`. You may
override this option with `\--no-abbrev-commit`.
log.date::
Set the default date-time mode for the 'log' command.

View File

@@ -8,6 +8,50 @@ diff.autorefreshindex::
affects only 'git diff' Porcelain, and not lower level
'diff' commands such as 'git diff-files'.
diff.dirstat::
A comma separated list of `--dirstat` parameters specifying the
default behavior of the `--dirstat` option to linkgit:git-diff[1]`
and friends. The defaults can be overridden on the command line
(using `--dirstat=<param1,param2,...>`). The fallback defaults
(when not changed by `diff.dirstat`) are `changes,noncumulative,3`.
The following parameters are available:
+
--
`changes`;;
Compute the dirstat numbers by counting the lines that have been
removed from the source, or added to the destination. This ignores
the amount of pure code movements within a file. In other words,
rearranging lines in a file is not counted as much as other changes.
This is the default behavior when no parameter is given.
`lines`;;
Compute the dirstat numbers by doing the regular line-based diff
analysis, and summing the removed/added line counts. (For binary
files, count 64-byte chunks instead, since binary files have no
natural concept of lines). This is a more expensive `--dirstat`
behavior than the `changes` behavior, but it does count rearranged
lines within a file as much as other changes. The resulting output
is consistent with what you get from the other `--*stat` options.
`files`;;
Compute the dirstat numbers by counting the number of files changed.
Each changed file counts equally in the dirstat analysis. This is
the computationally cheapest `--dirstat` behavior, since it does
not have to look at the file contents at all.
`cumulative`;;
Count changes in a child directory for the parent directory as well.
Note that when using `cumulative`, the sum of the percentages
reported may exceed 100%. The default (non-cumulative) behavior can
be specified with the `noncumulative` parameter.
<limit>;;
An integer parameter specifies a cut-off percent (3% by default).
Directories contributing less than this percentage of the changes
are not shown in the output.
--
+
Example: The following will count changed files, while ignoring
directories with less than 10% of the total amount of changed files,
and accumulating child directory counts in the parent directories:
`files,10,cumulative`.
diff.external::
If this config variable is set, diff generation is not
performed using the internal diff machinery, but using the

View File

@@ -48,11 +48,17 @@ endif::git-format-patch[]
--patience::
Generate a diff using the "patience diff" algorithm.
--stat[=<width>[,<name-width>]]::
--stat[=<width>[,<name-width>[,<count>]]]::
Generate a diffstat. You can override the default
output width for 80-column terminal by `--stat=<width>`.
The width of the filename part can be controlled by
giving another width to it separated by a comma.
By giving a third parameter `<count>`, you can limit the
output to the first `<count>` lines, followed by
`...` if there are more.
+
These parameters can also be set individually with `--stat-width=<width>`,
`--stat-name-width=<name-width>` and `--stat-count=<count>`.
--numstat::
Similar to `\--stat`, but shows number of added and
@@ -66,19 +72,49 @@ endif::git-format-patch[]
number of modified files, as well as number of added and deleted
lines.
--dirstat[=<limit>]::
Output the distribution of relative amount of changes (number of lines added or
removed) for each sub-directory. Directories with changes below
a cut-off percent (3% by default) are not shown. The cut-off percent
can be set with `--dirstat=<limit>`. Changes in a child directory are not
counted for the parent directory, unless `--cumulative` is used.
--dirstat[=<param1,param2,...>]::
Output the distribution of relative amount of changes for each
sub-directory. The behavior of `--dirstat` can be customized by
passing it a comma separated list of parameters.
The defaults are controlled by the `diff.dirstat` configuration
variable (see linkgit:git-config[1]).
The following parameters are available:
+
Note that the `--dirstat` option computes the changes while ignoring
the amount of pure code movements within a file. In other words,
rearranging lines in a file is not counted as much as other changes.
--dirstat-by-file[=<limit>]::
Same as `--dirstat`, but counts changed files instead of lines.
--
`changes`;;
Compute the dirstat numbers by counting the lines that have been
removed from the source, or added to the destination. This ignores
the amount of pure code movements within a file. In other words,
rearranging lines in a file is not counted as much as other changes.
This is the default behavior when no parameter is given.
`lines`;;
Compute the dirstat numbers by doing the regular line-based diff
analysis, and summing the removed/added line counts. (For binary
files, count 64-byte chunks instead, since binary files have no
natural concept of lines). This is a more expensive `--dirstat`
behavior than the `changes` behavior, but it does count rearranged
lines within a file as much as other changes. The resulting output
is consistent with what you get from the other `--*stat` options.
`files`;;
Compute the dirstat numbers by counting the number of files changed.
Each changed file counts equally in the dirstat analysis. This is
the computationally cheapest `--dirstat` behavior, since it does
not have to look at the file contents at all.
`cumulative`;;
Count changes in a child directory for the parent directory as well.
Note that when using `cumulative`, the sum of the percentages
reported may exceed 100%. The default (non-cumulative) behavior can
be specified with the `noncumulative` parameter.
<limit>;;
An integer parameter specifies a cut-off percent (3% by default).
Directories contributing less than this percentage of the changes
are not shown in the output.
--
+
Example: The following will count changed files, while ignoring
directories with less than 10% of the total amount of changed files,
and accumulating child directory counts in the parent directories:
`--dirstat=files,10,cumulative`.
--summary::
Output a condensed summary of extended header information
@@ -124,12 +160,19 @@ any of those replacements occurred.
--color[=<when>]::
Show colored diff.
The value must be always (the default), never, or auto.
The value must be `always` (the default for `<when>`), `never`, or `auto`.
The default value is `never`.
ifdef::git-diff[]
It can be changed by the `color.ui` and `color.diff`
configuration settings.
endif::git-diff[]
--no-color::
Turn off colored diff, even when the configuration file
gives the default to color output.
Same as `--color=never`.
Turn off colored diff.
ifdef::git-diff[]
This can be used to override configuration settings.
endif::git-diff[]
It is the same as `--color=never`.
--word-diff[=<mode>]::
Show a word diff, using the <mode> to delimit changed words.
@@ -243,7 +286,7 @@ ifdef::git-log[]
For following files across renames while traversing history, see
`--follow`.
endif::git-log[]
If `n` is specified, it is a is a threshold on the similarity
If `n` is specified, it is a threshold on the similarity
index (i.e. amount of addition/deletions compared to the
file's size). For example, `-M90%` means git should consider a
delete/add pair to be a rename if more than 90% of the file

View File

@@ -134,6 +134,8 @@ subdirectories.
If some files could not be added because of errors indexing
them, do not abort the operation, but continue adding the
others. The command shall still exit with non-zero status.
The configuration variable `add.ignoreErrors` can be set to
true to make this the default behaviour.
--ignore-missing::
This option can only be used together with --dry-run. By using
@@ -272,7 +274,8 @@ patch::
This lets you choose one path out of a 'status' like selection.
After choosing the path, it presents the diff between the index
and the working tree file and asks you if you want to stage
the change of each hunk. You can say:
the change of each hunk. You can select one of the following
options and type return:
y - stage this hunk
n - do not stage this hunk
@@ -291,6 +294,9 @@ patch::
+
After deciding the fate for all hunks, if there is any hunk
that was chosen, the index is updated with the selected hunks.
+
You can omit having to type return here, by setting the configuration
variable `interactive.singlekey` to `true`.
diff::

View File

@@ -105,6 +105,19 @@ The contents of the actual line is output after the above
header, prefixed by a TAB. This is to allow adding more
header elements later.
The porcelain format generally suppresses commit information that has
already been seen. For example, two lines that are blamed to the same
commit will both be shown, but the details for that commit will be shown
only once. This is more efficient, but may require more state be kept by
the reader. The `--line-porcelain` option can be used to output full
commit information for each line, allowing simpler (but less efficient)
usage like:
# count the number of lines attributed to each author
git blame --line-porcelain file |
sed -n 's/^author //p' |
sort | uniq -c | sort -rn
SPECIFYING RANGES
-----------------

View File

@@ -12,7 +12,7 @@ SYNOPSIS
'git checkout' [-q] [-f] [-m] [--detach] [<commit>]
'git checkout' [-q] [-f] [-m] [[-b|-B|--orphan] <new_branch>] [<start_point>]
'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>...
'git checkout' --patch [<tree-ish>] [--] [<paths>...]
'git checkout' [-p|--patch] [<tree-ish>] [--] [<paths>...]
DESCRIPTION
-----------
@@ -45,7 +45,7 @@ $ git checkout <branch>
that is to say, the branch is not reset/created unless "git checkout" is
successful.
'git checkout' [--patch] [<tree-ish>] [--] <pathspec>...::
'git checkout' [-p|--patch] [<tree-ish>] [--] <pathspec>...::
When <paths> or `--patch` are given, 'git checkout' does *not*
switch branches. It updates the named paths in the working tree
@@ -183,7 +183,8 @@ the conflicted merge in the specified paths.
working tree (and if a <tree-ish> was specified, the index).
+
This means that you can use `git checkout -p` to selectively discard
edits from your current working tree.
edits from your current working tree. See the ``Interactive Mode''
section of linkgit:git-add[1] to learn how to operate the `\--patch` mode.
<branch>::
Branch to checkout; if it refers to a branch (i.e., a name that,

View File

@@ -51,9 +51,10 @@ OPTIONS
message prior to committing.
-x::
When recording the commit, append to the original commit
message a note that indicates which commit this change
was cherry-picked from. Append the note only for cherry
When recording the commit, append a line that says
"(cherry picked from commit ...)" to the original commit
message in order to indicate which commit this change was
cherry-picked from. This is done only for cherry
picks without conflicts. Do not use this option if
you are cherry-picking from your private branch because
the information is useless to the recipient. If on the

View File

@@ -12,7 +12,7 @@ SYNOPSIS
'git clone' [--template=<template_directory>]
[-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror]
[-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>]
[--separate-git-dir|-L <git dir>]
[--separate-git-dir <git dir>]
[--depth <depth>] [--recursive|--recurse-submodules] [--] <repository>
[<directory>]
@@ -177,7 +177,6 @@ objects from the source repository into a pack in the cloned repository.
repository does not have a worktree/checkout (i.e. if any of
`--no-checkout`/`-n`, `--bare`, or `--mirror` is given)
-L=<git dir>::
--separate-git-dir=<git dir>::
Instead of placing the cloned repository where it is supposed
to be, place the cloned repository at the specified directory,

View File

@@ -8,11 +8,12 @@ git-commit - Record changes to the repository
SYNOPSIS
--------
[verse]
'git commit' [-a | --interactive] [-s] [-v] [-u<mode>] [--amend] [--dry-run]
[(-c | -C | --fixup | --squash) <commit>] [-F <file> | -m <msg>]
[--reset-author] [--allow-empty] [--allow-empty-message] [--no-verify]
[-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>]
[--status | --no-status] [-i | -o] [--] [<file>...]
'git commit' [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]
[--dry-run] [(-c | -C | --fixup | --squash) <commit>]
[-F <file> | -m <msg>] [--reset-author] [--allow-empty]
[--allow-empty-message] [--no-verify] [-e] [--author=<author>]
[--date=<date>] [--cleanup=<mode>] [--status | --no-status]
[-i | -o] [--] [<file>...]
DESCRIPTION
-----------
@@ -39,9 +40,10 @@ The content to be added can be specified in several ways:
that have been removed from the working tree, and then perform the
actual commit;
5. by using the --interactive switch with the 'commit' command to decide one
by one which files should be part of the commit, before finalizing the
operation. Currently, this is done by invoking 'git add --interactive'.
5. by using the --interactive or --patch switches with the 'commit' command
to decide one by one which files or hunks should be part of the commit,
before finalizing the operation. See the ``Interactive Mode`` section of
linkgit:git-add[1] to learn how to operate these modes.
The `--dry-run` option can be used to obtain a
summary of what is included by any of the above for the next
@@ -59,6 +61,12 @@ OPTIONS
been modified and deleted, but new files you have not
told git about are not affected.
-p::
--patch::
Use the interactive patch selection interface to chose
which changes to commit. See linkgit:git-add[1] for
details.
-C <commit>::
--reuse-message=<commit>::
Take an existing commit object, and reuse the log message

View File

@@ -50,16 +50,18 @@ The default is to assume the config file of the current repository,
.git/config unless defined otherwise with GIT_DIR and GIT_CONFIG
(see <<FILES>>).
This command will fail if:
This command will fail (with exit code ret) if:
. The config file is invalid,
. Can not write to the config file,
. no section was provided,
. the section or key is invalid,
. you try to unset an option which does not exist,
. you try to unset/set an option for which multiple lines match, or
. you use '--global' option without $HOME being properly set.
. The config file is invalid (ret=3),
. can not write to the config file (ret=4),
. no section or name was provided (ret=2),
. the section or key is invalid (ret=1),
. you try to unset an option which does not exist (ret=5),
. you try to unset/set an option for which multiple lines match (ret=5),
. you try to use an invalid regexp (ret=6), or
. you use '--global' option without $HOME being properly set (ret=128).
On success, the command returns the exit code 0.
OPTIONS
-------

View File

@@ -252,7 +252,7 @@ Configuring database backend
'git-cvsserver' uses the Perl DBI module. Please also read
its documentation if changing these variables, especially
about `DBI->connect()`.
about `DBI\->connect()`.
gitcvs.dbname::
Database name. The exact meaning depends on the

View File

@@ -96,8 +96,8 @@ show that. So let's say that you have edited `kernel/sched.c`, but
have not actually done a 'git update-index' on it yet - there is no
"object" associated with the new state, and you get:
torvalds@ppc970:~/v2.6/linux> git diff-index HEAD
*100644->100664 blob 7476bb......->000000...... kernel/sched.c
torvalds@ppc970:~/v2.6/linux> git diff-index --abbrev HEAD
:100644 100664 7476bb... 000000... kernel/sched.c
i.e., it shows that the tree has changed, and that `kernel/sched.c` has is
not up-to-date and may contain new stuff. The all-zero sha1 means that to

View File

@@ -138,8 +138,8 @@ so it can be used to name subdirectories.
An example of normal usage is:
torvalds@ppc970:~/git> git diff-tree 5319e4......
*100664->100664 blob ac348b.......->a01513....... git-fsck-objects.c
torvalds@ppc970:~/git> git diff-tree --abbrev 5319e4
:100664 100664 ac348b... a01513... git-fsck-objects.c
which tells you that the last commit changed just one file (it's from
this one:

View File

@@ -83,7 +83,7 @@ OPTIONS
skips the file if it does not exist.
--relative-marks::
After specifying --relative-marks= the paths specified
After specifying --relative-marks the paths specified
with --import-marks= and --export-marks= are relative
to an internal directory in the current repository.
In git-fast-import this means that the paths are relative
@@ -93,7 +93,7 @@ OPTIONS
--no-relative-marks::
Negates a previous --relative-marks. Allows for combining
relative and non-relative marks by interweaving
--(no-)-relative-marks= with the --(import|export)-marks=
--(no-)-relative-marks with the --(import|export)-marks=
options.
--cat-blob-fd=<fd>::

View File

@@ -232,6 +232,233 @@ attachments, and sign off patches with configuration variables.
------------
DISCUSSION
----------
The patch produced by 'git format-patch' is in UNIX mailbox format,
with a fixed "magic" time stamp to indicate that the file is output
from format-patch rather than a real mailbox, like so:
------------
From 8f72bad1baf19a53459661343e21d6491c3908d3 Mon Sep 17 00:00:00 2001
From: Tony Luck <tony.luck@intel.com>
Date: Tue, 13 Jul 2010 11:42:54 -0700
Subject: [PATCH] =?UTF-8?q?[IA64]=20Put=20ia64=20config=20files=20on=20the=20?=
=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig=20diet?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
arch/arm config files were slimmed down using a python script
(See commit c2330e286f68f1c408b4aa6515ba49d57f05beae comment)
Do the same for ia64 so we can have sleek & trim looking
...
------------
Typically it will be placed in a MUA's drafts folder, edited to add
timely commentary that should not go in the changelog after the three
dashes, and then sent as a message whose body, in our example, starts
with "arch/arm config files were...". On the receiving end, readers
can save interesting patches in a UNIX mailbox and apply them with
linkgit:git-am[1].
When a patch is part of an ongoing discussion, the patch generated by
'git format-patch' can be tweaked to take advantage of the 'git am
--scissors' feature. After your response to the discussion comes a
line that consists solely of "`-- >8 --`" (scissors and perforation),
followed by the patch with unnecessary header fields removed:
------------
...
> So we should do such-and-such.
Makes sense to me. How about this patch?
-- >8 --
Subject: [IA64] Put ia64 config files on the Uwe Kleine-König diet
arch/arm config files were slimmed down using a python script
...
------------
When sending a patch this way, most often you are sending your own
patch, so in addition to the "`From $SHA1 $magic_timestamp`" marker you
should omit `From:` and `Date:` lines from the patch file. The patch
title is likely to be different from the subject of the discussion the
patch is in response to, so it is likely that you would want to keep
the Subject: line, like the example above.
Checking for patch corruption
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Many mailers if not set up properly will corrupt whitespace. Here are
two common types of corruption:
* Empty context lines that do not have _any_ whitespace.
* Non-empty context lines that have one extra whitespace at the
beginning.
One way to test if your MUA is set up correctly is:
* Send the patch to yourself, exactly the way you would, except
with To: and Cc: lines that do not contain the list and
maintainer address.
* Save that patch to a file in UNIX mailbox format. Call it a.patch,
say.
* Apply it:
$ git fetch <project> master:test-apply
$ git checkout test-apply
$ git reset --hard
$ git am a.patch
If it does not apply correctly, there can be various reasons.
* The patch itself does not apply cleanly. That is _bad_ but
does not have much to do with your MUA. You might want to rebase
the patch with linkgit:git-rebase[1] before regenerating it in
this case.
* The MUA corrupted your patch; "am" would complain that
the patch does not apply. Look in the .git/rebase-apply/ subdirectory and
see what 'patch' file contains and check for the common
corruption patterns mentioned above.
* While at it, check the 'info' and 'final-commit' files as well.
If what is in 'final-commit' is not exactly what you would want to
see in the commit log message, it is very likely that the
receiver would end up hand editing the log message when applying
your patch. Things like "Hi, this is my first patch.\n" in the
patch e-mail should come after the three-dash line that signals
the end of the commit message.
MUA-SPECIFIC HINTS
------------------
Here are some hints on how to successfully submit patches inline using
various mailers.
GMail
~~~~~
GMail does not have any way to turn off line wrapping in the web
interface, so it will mangle any emails that you send. You can however
use "git send-email" and send your patches through the GMail SMTP server, or
use any IMAP email client to connect to the google IMAP server and forward
the emails through that.
For hints on using 'git send-email' to send your patches through the
GMail SMTP server, see the EXAMPLE section of linkgit:git-send-email[1].
For hints on submission using the IMAP interface, see the EXAMPLE
section of linkgit:git-imap-send[1].
Thunderbird
~~~~~~~~~~~
By default, Thunderbird will both wrap emails as well as flag
them as being 'format=flowed', both of which will make the
resulting email unusable by git.
There are three different approaches: use an add-on to turn off line wraps,
configure Thunderbird to not mangle patches, or use
an external editor to keep Thunderbird from mangling the patches.
Approach #1 (add-on)
^^^^^^^^^^^^^^^^^^^^
Install the Toggle Word Wrap add-on that is available from
https://addons.mozilla.org/thunderbird/addon/toggle-word-wrap/
It adds a menu entry "Enable Word Wrap" in the composer's "Options" menu
that you can tick off. Now you can compose the message as you otherwise do
(cut + paste, 'git format-patch' | 'git imap-send', etc), but you have to
insert line breaks manually in any text that you type.
Approach #2 (configuration)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Three steps:
1. Configure your mail server composition as plain text:
Edit...Account Settings...Composition & Addressing,
uncheck "Compose Messages in HTML".
2. Configure your general composition window to not wrap.
+
In Thunderbird 2:
Edit..Preferences..Composition, wrap plain text messages at 0
+
In Thunderbird 3:
Edit..Preferences..Advanced..Config Editor. Search for
"mail.wrap_long_lines".
Toggle it to make sure it is set to `false`.
3. Disable the use of format=flowed:
Edit..Preferences..Advanced..Config Editor. Search for
"mailnews.send_plaintext_flowed".
Toggle it to make sure it is set to `false`.
After that is done, you should be able to compose email as you
otherwise would (cut + paste, 'git format-patch' | 'git imap-send', etc),
and the patches will not be mangled.
Approach #3 (external editor)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The following Thunderbird extensions are needed:
AboutConfig from http://aboutconfig.mozdev.org/ and
External Editor from http://globs.org/articles.php?lng=en&pg=8
1. Prepare the patch as a text file using your method of choice.
2. Before opening a compose window, use Edit->Account Settings to
uncheck the "Compose messages in HTML format" setting in the
"Composition & Addressing" panel of the account to be used to
send the patch.
3. In the main Thunderbird window, 'before' you open the compose
window for the patch, use Tools->about:config to set the
following to the indicated values:
+
----------
mailnews.send_plaintext_flowed => false
mailnews.wraplength => 0
----------
4. Open a compose window and click the external editor icon.
5. In the external editor window, read in the patch file and exit
the editor normally.
Side note: it may be possible to do step 2 with
about:config and the following settings but no one's tried yet.
----------
mail.html_compose => false
mail.identity.default.compose_html => false
mail.identity.id?.compose_html => false
----------
There is a script in contrib/thunderbird-patch-inline which can help
you include patches with Thunderbird in an easy way. To use it, do the
steps above and then use the script as the external editor.
KMail
~~~~~
This should help you to submit patches inline using KMail.
1. Prepare the patch as a text file.
2. Click on New Mail.
3. Go under "Options" in the Composer window and be sure that
"Word wrap" is not set.
4. Use Message -> Insert file... and insert the patch.
5. Back in the compose window: add whatever other text you wish to the
message, complete the addressing and subject fields, and press send.
EXAMPLES
--------

View File

@@ -26,7 +26,7 @@ index file, all SHA1 references in .git/refs/*, and all reflogs (unless
--no-reflogs is given) as heads.
--unreachable::
Print out objects that exist but that aren't readable from any
Print out objects that exist but that aren't reachable from any
of the reference nodes.
--root::
@@ -76,7 +76,7 @@ It tests SHA1 and general object sanity, and it does full tracking of
the resulting reachability and everything else. It prints out any
corruption it finds (missing or bad objects), and if you use the
'--unreachable' flag it will also print out objects that exist but
that aren't readable from any of the specified head nodes.
that aren't reachable from any of the specified head nodes.
So for example

View File

@@ -12,7 +12,8 @@ SYNOPSIS
'git grep' [-a | --text] [-I] [-i | --ignore-case] [-w | --word-regexp]
[-v | --invert-match] [-h|-H] [--full-name]
[-E | --extended-regexp] [-G | --basic-regexp]
[-F | --fixed-strings] [-n]
[-P | --perl-regexp]
[-F | --fixed-strings] [-n | --line-number]
[-l | --files-with-matches] [-L | --files-without-match]
[(-O | --open-files-in-pager) [<pager>]]
[-z | --null]
@@ -97,6 +98,11 @@ OPTIONS
Use POSIX extended/basic regexp for patterns. Default
is to use basic regexp.
-P::
--perl-regexp::
Use Perl-compatible regexp for patterns. Requires libpcre to be
compiled in.
-F::
--fixed-strings::
Use fixed strings for patterns (don't interpret pattern

View File

@@ -111,6 +111,31 @@ Using direct mode with SSL:
..........................
EXAMPLE
-------
To submit patches using GMail's IMAP interface, first, edit your ~/.gitconfig
to specify your account settings:
---------
[imap]
folder = "[Gmail]/Drafts"
host = imaps://imap.gmail.com
user = user@gmail.com
port = 993
sslverify = false
---------
You might need to instead use: folder = "[Google Mail]/Drafts" if you get an error
that the "Folder doesn't exist".
Once the commits are ready to be sent, run the following command:
$ git format-patch --cover-letter -M --stdout origin/master | git imap-send
Just make sure to disable line wrapping in the email client (GMail's web
interface will wrap lines no matter what, so you need to use a real
IMAP client).
CAUTION
-------
It is still your responsibility to make sure that the email message
@@ -124,6 +149,10 @@ Thunderbird in particular is known to be problematic. Thunderbird
users may wish to visit this web page for more information:
http://kb.mozillazine.org/Plain_text_e-mail_-_Thunderbird#Completely_plain_email
SEE ALSO
--------
linkgit:git-format-patch[1], linkgit:git-send-email[1], mbox(5)
GIT
---
Part of the linkgit:git[1] suite

View File

@@ -8,7 +8,7 @@ git-init-db - Creates an empty git repository
SYNOPSIS
--------
'git init-db' [-q | --quiet] [--bare] [--template=<template_directory>] [--shared[=<permissions>]]
'git init-db' [-q | --quiet] [--bare] [--template=<template_directory>] [--separate-git-dir <git dir>] [--shared[=<permissions>]]
DESCRIPTION

View File

@@ -9,7 +9,7 @@ git-init - Create an empty git repository or reinitialize an existing one
SYNOPSIS
--------
'git init' [-q | --quiet] [--bare] [--template=<template_directory>]
[--separate-git-dir|-L <git dir>]
[--separate-git-dir <git dir>]
[--shared[=<permissions>]] [directory]
@@ -54,7 +54,6 @@ current working directory.
Specify the directory from which templates will be used. (See the "TEMPLATE
DIRECTORY" section below.)
-L=<git dir>::
--separate-git-dir=<git dir>::
Instead of initializing the repository where it is supposed to be,

View File

@@ -10,7 +10,7 @@ SYNOPSIS
--------
[verse]
'git ls-remote' [--heads] [--tags] [-u <exec> | --upload-pack <exec>]
<repository> [<refs>...]
[--exit-code] <repository> [<refs>...]
DESCRIPTION
-----------
@@ -36,6 +36,12 @@ OPTIONS
SSH and where the SSH daemon does not use the PATH configured by the
user.
--exit-code::
Exit with status "2" when no matching refs are found in the remote
repository. Usually the command exits with status "0" to indicate
it successfully talked with the remote repository, whether it
found any matching refs.
<repository>::
Location of the repository. The shorthand defined in
$GIT_DIR/branches/ can be used. Use "." (dot) to list references in

View File

@@ -9,7 +9,8 @@ git-merge-base - Find as good common ancestors as possible for a merge
SYNOPSIS
--------
[verse]
'git merge-base' [-a|--all] [--octopus] <commit> <commit>...
'git merge-base' [-a|--all] <commit> <commit>...
'git merge-base' [-a|--all] --octopus <commit>...
'git merge-base' --independent <commit>...
DESCRIPTION
@@ -22,23 +23,21 @@ that does not have any better common ancestor is a 'best common
ancestor', i.e. a 'merge base'. Note that there can be more than one
merge base for a pair of commits.
Unless `--octopus` is given, among the two commits to compute the merge
base from, one is specified by the first commit argument on the command
line; the other commit is a (possibly hypothetical) commit that is a merge
across all the remaining commits on the command line. As the most common
special case, specifying only two commits on the command line means
computing the merge base between the given two commits.
OPERATION MODE
--------------
As the most common special case, specifying only two commits on the
command line means computing the merge base between the given two commits.
More generally, among the two commits to compute the merge base from,
one is specified by the first commit argument on the command line;
the other commit is a (possibly hypothetical) commit that is a merge
across all the remaining commits on the command line.
As a consequence, the 'merge base' is not necessarily contained in each of the
commit arguments if more than two commits are specified. This is different
from linkgit:git-show-branch[1] when used with the `--merge-base` option.
OPTIONS
-------
-a::
--all::
Output all merge bases for the commits, instead of just one.
--octopus::
Compute the best common ancestors of all supplied commits,
in preparation for an n-way merge. This mimics the behavior
@@ -51,6 +50,12 @@ OPTIONS
from any other. This mimics the behavior of 'git show-branch
--independent'.
OPTIONS
-------
-a::
--all::
Output all merge bases for the commits, instead of just one.
DISCUSSION
----------
@@ -89,6 +94,9 @@ and the result of `git merge-base A M` is '1'. Commit '2' is also a
common ancestor between 'A' and 'M', but '1' is a better common ancestor,
because '2' is an ancestor of '1'. Hence, '2' is not a merge base.
The result of `git merge-base --octopus A B C` is '2', because '2' is
the best common ancestor of all commits.
When the history involves criss-cross merges, there can be more than one
'best' common ancestor for two commits. For example, with this topology:

View File

@@ -17,7 +17,7 @@ SYNOPSIS
'git notes' merge [-v | -q] [-s <strategy> ] <notes_ref>
'git notes' merge --commit [-v | -q]
'git notes' merge --abort [-v | -q]
'git notes' remove [<object>]
'git notes' remove [--ignore-missing] [--stdin] [<object>...]
'git notes' prune [-n | -v]
'git notes' get-ref
@@ -106,8 +106,9 @@ When done, the user can either finalize the merge with
'git notes merge --abort'.
remove::
Remove the notes for a given object (defaults to HEAD).
This is equivalent to specifying an empty note message to
Remove the notes for given objects (defaults to HEAD). When
giving zero or one object from the command line, this is
equivalent to specifying an empty note message to
the `edit` subcommand.
prune::
@@ -154,6 +155,15 @@ OPTIONS
'GIT_NOTES_REF' and the "core.notesRef" configuration. The ref
is taken to be in `refs/notes/` if it is not qualified.
--ignore-missing::
Do not consider it an error to request removing notes from an
object that does not have notes attached to it.
--stdin::
Also read the object names to remove notes from from the standard
input (there is no reason you cannot combine this with object
names from the command line).
-n::
--dry-run::
Do not remove anything; just report the object names whose notes

View File

@@ -53,6 +53,11 @@ OPTIONS
trees that are not directly related to the current
working tree status into a temporary index file.
-n::
--dry-run::
Check if the command would error out, without updating the index
nor the files in the working tree for real.
-v::
Show the progress of checking files out.

View File

@@ -181,11 +181,11 @@ CAPABILITIES
When using the import command, expect the source ref to have
been written to the destination ref. The earliest applicable
refspec takes precedence. For example
"refs/heads/*:refs/svn/origin/branches/*" means that, after an
"import refs/heads/name", the script has written to
"refs/heads/{asterisk}:refs/svn/origin/branches/{asterisk}" means
that, after an "import refs/heads/name", the script has written to
refs/svn/origin/branches/name. If this capability is used at
all, it must cover all refs reported by the list command; if
it is not used, it is effectively "*:*"
it is not used, it is effectively "{asterisk}:{asterisk}"
REF LIST ATTRIBUTES
-------------------

View File

@@ -9,7 +9,7 @@ SYNOPSIS
--------
[verse]
'git reset' [-q] [<commit>] [--] <paths>...
'git reset' --patch [<commit>] [--] [<paths>...]
'git reset' [--patch|-p] [<commit>] [--] [<paths>...]
'git reset' [--soft | --mixed | --hard | --merge | --keep] [-q] [<commit>]
DESCRIPTION
@@ -39,8 +39,9 @@ working tree in one go.
and <commit> (defaults to HEAD). The chosen hunks are applied
in reverse to the index.
+
This means that `git reset -p` is the opposite of `git add -p` (see
linkgit:git-add[1]).
This means that `git reset -p` is the opposite of `git add -p`, i.e.
you can use it to selectively reset hunks. See the ``Interactive Mode''
section of linkgit:git-add[1] to learn how to operate the `\--patch` mode.
'git reset' [--<mode>] [<commit>]::
This form resets the current branch head to <commit> and

View File

@@ -29,6 +29,7 @@ SYNOPSIS
[ \--tags[=<pattern>] ]
[ \--remotes[=<pattern>] ]
[ \--glob=<glob-pattern> ]
[ \--ignore-missing ]
[ \--stdin ]
[ \--quiet ]
[ \--topo-order ]

View File

@@ -348,10 +348,12 @@ sendemail.confirm::
one of 'always', 'never', 'cc', 'compose', or 'auto'. See '--confirm'
in the previous section for the meaning of these values.
EXAMPLE
-------
Use gmail as the smtp server
----------------------------
Add the following section to the config file:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To use 'git send-email' to send your patches through the GMail SMTP server,
edit ~/.gitconfig to specify your account settings:
[sendemail]
smtpencryption = tls
@@ -359,9 +361,20 @@ Add the following section to the config file:
smtpuser = yourname@gmail.com
smtpserverport = 587
Once your commits are ready to be sent to the mailing list, run the
following commands:
$ git format-patch --cover-letter -M origin/master -o outgoing/
$ edit outgoing/0000-*
$ git send-email outgoing/*
Note: the following perl modules are required
Net::SMTP::SSL, MIME::Base64 and Authen::SASL
SEE ALSO
--------
linkgit:git-format-patch[1], linkgit:git-imap-send[1], mbox(5)
GIT
---
Part of the linkgit:git[1] suite

View File

@@ -0,0 +1,36 @@
git-sh-i18n--envsubst(1)
========================
NAME
----
git-sh-i18n--envsubst - Git's own envsubst(1) for i18n fallbacks
SYNOPSIS
--------
[verse]
eval_gettext () {
printf "%s" "$1" | (
export PATH $('git sh-i18n--envsubst' --variables "$1");
'git sh-i18n--envsubst' "$1"
)
}
DESCRIPTION
-----------
This is not a command the end user would want to run. Ever.
This documentation is meant for people who are studying the
plumbing scripts and/or are writing new ones.
git-sh-i18n--envsubst is Git's stripped-down copy of the GNU
`envsubst(1)` program that comes with the GNU gettext package. It's
used internally by linkgit:git-sh-i18n[1] to interpolate the variables
passed to the the `eval_gettext` function.
No promises are made about the interface, or that this
program won't disappear without warning in the next version
of Git. Don't use it.
GIT
---
Part of the linkgit:git[1] suite

View File

@@ -0,0 +1,42 @@
git-sh-i18n(1)
==============
NAME
----
git-sh-i18n - Git's i18n setup code for shell scripts
SYNOPSIS
--------
'. "$(git --exec-path)/git-sh-i18n"'
DESCRIPTION
-----------
This is not a command the end user would want to run. Ever.
This documentation is meant for people who are studying the
Porcelain-ish scripts and/or are writing new ones.
The 'git sh-i18n scriptlet is designed to be sourced (using
`.`) by Git's porcelain programs implemented in shell
script. It provides wrappers for the GNU `gettext` and
`eval_gettext` functions accessible through the `gettext.sh`
script, and provides pass-through fallbacks on systems
without GNU gettext.
FUNCTIONS
---------
gettext::
Currently a dummy fall-through function implemented as a wrapper
around `printf(1)`. Will be replaced by a real gettext
implementation in a later version.
eval_gettext::
Currently a dummy fall-through function implemented as a wrapper
around `printf(1)` with variables expanded by the
linkgit:git-sh-i18n--envsubst[1] helper. Will be replaced by a
real gettext implementation in a later version.
GIT
---
Part of the linkgit:git[1] suite

View File

@@ -58,9 +58,14 @@ cd_to_toplevel::
runs chdir to the toplevel of the working tree.
require_work_tree::
checks if the repository is a bare repository, and dies
if so. Used by scripts that require working tree
(e.g. `checkout`).
checks if the current directory is within the working tree
of the repository, and otherwise dies.
require_work_tree_exists::
checks if the working tree associated with the repository
exists, and otherwise dies. Often done before calling
cd_to_toplevel, which is impossible to do if there is no
working tree.
get_author_ident_from_commit::
outputs code for use with eval to set the GIT_AUTHOR_NAME,

View File

@@ -13,7 +13,7 @@ SYNOPSIS
'git stash' drop [-q|--quiet] [<stash>]
'git stash' ( pop | apply ) [--index] [-q|--quiet] [<stash>]
'git stash' branch <branchname> [<stash>]
'git stash' [save [--patch] [-k|--[no-]keep-index] [-q|--quiet] [<message>]]
'git stash' [save [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet] [<message>]]
'git stash' clear
'git stash' create
@@ -42,7 +42,7 @@ is also possible).
OPTIONS
-------
save [--patch] [--[no-]keep-index] [-q|--quiet] [<message>]::
save [-p|--patch] [--[no-]keep-index] [-q|--quiet] [<message>]::
Save your local modifications to a new 'stash', and run `git reset
--hard` to revert them. The <message> part is optional and gives
@@ -54,12 +54,13 @@ save [--patch] [--[no-]keep-index] [-q|--quiet] [<message>]::
If the `--keep-index` option is used, all changes already added to the
index are left intact.
+
With `--patch`, you can interactively select hunks from in the diff
With `--patch`, you can interactively select hunks from the diff
between HEAD and the working tree to be stashed. The stash entry is
constructed such that its index state is the same as the index state
of your repository, and its worktree contains only the changes you
selected interactively. The selected changes are then rolled back
from your worktree.
from your worktree. See the ``Interactive Mode'' section of
linkgit:git-add[1] to learn how to operate the `\--patch` mode.
+
The `--patch` option implies `--keep-index`. You can use
`--no-keep-index` to override this.

View File

@@ -32,9 +32,10 @@ OPTIONS
Show the branch and tracking info even in short-format.
--porcelain::
Give the output in a stable, easy-to-parse format for scripts.
Currently this is identical to --short output, but is guaranteed
not to change in the future, making it safe for scripts.
Give the output in an easy-to-parse format for scripts.
This is similar to the short output, but will remain stable
across git versions and regardless of user configuration. See
below for details.
-u[<mode>]::
--untracked-files[=<mode>]::
@@ -78,23 +79,27 @@ OUTPUT
The output from this command is designed to be used as a commit
template comment, and all the output lines are prefixed with '#'.
The default, long format, is designed to be human readable,
verbose and descriptive. They are subject to change in any time.
verbose and descriptive. Its contents and format are subject to change
at any time.
The paths mentioned in the output, unlike many other git commands, are
made relative to the current directory if you are working in a
subdirectory (this is on purpose, to help cutting and pasting). See
the status.relativePaths config option below.
In short-format, the status of each path is shown as
Short Format
~~~~~~~~~~~~
In the short-format, the status of each path is shown as
XY PATH1 -> PATH2
where `PATH1` is the path in the `HEAD`, and ` -> PATH2` part is
where `PATH1` is the path in the `HEAD`, and the ` \-> PATH2` part is
shown only when `PATH1` corresponds to a different path in the
index/worktree (i.e. the file is renamed). The 'XY' is a two-letter
status code.
The fields (including the `->`) are separated from each other by a
The fields (including the `\->`) are separated from each other by a
single space. If a filename contains whitespace or other nonprintable
characters, that field will be quoted in the manner of a C string
literal: surrounded by ASCII double quote (34) characters, and with
@@ -143,10 +148,25 @@ If -b is used the short-format status is preceded by a line
## branchname tracking info
There is an alternate -z format recommended for machine parsing. In
Porcelain Format
~~~~~~~~~~~~~~~~
The porcelain format is similar to the short format, but is guaranteed
not to change in a backwards-incompatible way between git versions or
based on user configuration. This makes it ideal for parsing by scripts.
The description of the short format above also describes the porcelain
format, with a few exceptions:
1. The user's color.status configuration is not respected; color will
always be off.
2. The user's status.relativePaths configuration is not respected; paths
shown will always be relative to the repository root.
There is also an alternate -z format recommended for machine parsing. In
that format, the status field is the same, but some other things
change. First, the '->' is omitted from rename entries and the field
order is reversed (e.g 'from -> to' becomes 'to from'). Second, a NUL
change. First, the '\->' is omitted from rename entries and the field
order is reversed (e.g 'from \-> to' becomes 'to from'). Second, a NUL
(ASCII 0) follows each filename, replacing space as a field separator
and the terminating newline (but a space still separates the status
field from the first filename). Third, filenames containing special

View File

@@ -145,17 +145,6 @@ Skip "branches" and "tags" of first level directories;;
------------------------------------------------------------------------
--
--use-log-author;;
When retrieving svn commits into git (as part of fetch, rebase, or
dcommit operations), look for the first From: or Signed-off-by: line
in the log message and use that as the author string.
--add-author-from;;
When committing to svn from git (as part of commit or dcommit
operations), if the existing log message doesn't already have a
From: or Signed-off-by: line, append a From: line based on the
git commit's author string. If you use this, then --use-log-author
will retrieve a valid author string for all commits.
'clone'::
Runs 'init' and 'fetch'. It will automatically create a
directory based on the basename of the URL passed to it;
@@ -574,6 +563,17 @@ repository that will be fetched from.
For 'branch' and 'tag', display the urls that will be used for copying when
creating the branch or tag.
--use-log-author::
When retrieving svn commits into git (as part of 'fetch', 'rebase', or
'dcommit' operations), look for the first `From:` or `Signed-off-by:` line
in the log message and use that as the author string.
--add-author-from::
When committing to svn from git (as part of 'commit-diff', 'set-tree' or 'dcommit'
operations), if the existing log message doesn't already have a
`From:` or `Signed-off-by:` line, append a `From:` line based on the
git commit's author string. If you use this, then `--use-log-author`
will retrieve a valid author string for all commits.
ADVANCED OPTIONS
----------------
@@ -784,10 +784,9 @@ use `git svn rebase` to update your work branch instead of `git pull` or
when committing into SVN, which can lead to merge commits reversing
previous commits in SVN.
DESIGN PHILOSOPHY
-----------------
Merge tracking in Subversion is lacking and doing branched development
with Subversion can be cumbersome as a result. While 'git svn' can track
MERGE TRACKING
--------------
While 'git svn' can track
copy history (including branches and tags) for repositories adopting a
standard layout, it cannot yet represent merge history that happened
inside git back upstream to SVN users. Therefore it is advised that
@@ -797,16 +796,15 @@ compatibility with SVN (see the CAVEATS section below).
CAVEATS
-------
For the sake of simplicity and interoperating with a less-capable system
(SVN), it is recommended that all 'git svn' users clone, fetch and dcommit
For the sake of simplicity and interoperating with Subversion,
it is recommended that all 'git svn' users clone, fetch and dcommit
directly from the SVN server, and avoid all 'git clone'/'pull'/'merge'/'push'
operations between git repositories and branches. The recommended
method of exchanging code between git branches and users is
'git format-patch' and 'git am', or just 'dcommit'ing to the SVN repository.
Running 'git merge' or 'git pull' is NOT recommended on a branch you
plan to 'dcommit' from. Subversion does not represent merges in any
reasonable or useful fashion; so users using Subversion cannot see any
plan to 'dcommit' from because Subversion users cannot see any
merges you've made. Furthermore, if you merge or pull from a git branch
that is a mirror of an SVN branch, 'dcommit' may commit to the wrong
branch.
@@ -856,7 +854,7 @@ Renamed and copied directories are not detected by git and hence not
tracked when committing to SVN. I do not plan on adding support for
this as it's quite difficult and time-consuming to get working for all
the possible corner cases (git doesn't do it, either). Committing
renamed and copied files are fully supported if they're similar enough
renamed and copied files is fully supported if they're similar enough
for git to detect them.
CONFIGURATION

View File

@@ -9,7 +9,7 @@ git - the stupid content tracker
SYNOPSIS
--------
[verse]
'git' [--version] [--exec-path[=<path>]] [--html-path]
'git' [--version] [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
[-p|--paginate|--no-pager] [--no-replace-objects]
[--bare] [--git-dir=<path>] [--work-tree=<path>]
[-c <name>=<value>]
@@ -44,9 +44,13 @@ unreleased) version of git, that is available from 'master'
branch of the `git.git` repository.
Documentation for older releases are available here:
* link:v1.7.5/git.html[documentation for release 1.7.5]
* link:v1.7.5.4/git.html[documentation for release 1.7.5.4]
* release notes for
link:RelNotes/1.7.5.4.txt[1.7.5.4],
link:RelNotes/1.7.5.3.txt[1.7.5.3],
link:RelNotes/1.7.5.2.txt[1.7.5.2],
link:RelNotes/1.7.5.1.txt[1.7.5.1],
link:RelNotes/1.7.5.txt[1.7.5].
* link:v1.7.4.5/git.html[documentation for release 1.7.4.5]
@@ -287,8 +291,16 @@ help ...`.
the current setting and then exit.
--html-path::
Print the path to wherever your git HTML documentation is installed
and exit.
Print the path, without trailing slash, where git's HTML
documentation is installed and exit.
--man-path::
Print the manpath (see `man(1)`) for the man pages for
this version of git and exit.
--info-path::
Print the path where the Info files documenting this
version of git are installed and exit.
-p::
--paginate::

View File

@@ -593,6 +593,37 @@ and now produces better output), you can remove the cache
manually with `git update-ref -d refs/notes/textconv/jpg` (where
"jpg" is the name of the diff driver, as in the example above).
Choosing textconv versus external diff
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you want to show differences between binary or specially-formatted
blobs in your repository, you can choose to use either an external diff
command, or to use textconv to convert them to a diff-able text format.
Which method you choose depends on your exact situation.
The advantage of using an external diff command is flexibility. You are
not bound to find line-oriented changes, nor is it necessary for the
output to resemble unified diff. You are free to locate and report
changes in the most appropriate way for your data format.
A textconv, by comparison, is much more limiting. You provide a
transformation of the data into a line-oriented text format, and git
uses its regular diff tools to generate the output. There are several
advantages to choosing this method:
1. Ease of use. It is often much simpler to write a binary to text
transformation than it is to perform your own diff. In many cases,
existing programs can be used as textconv filters (e.g., exif,
odt2txt).
2. Git diff features. By performing only the transformation step
yourself, you can still utilize many of git's diff features,
including colorization, word-diff, and combined diffs for merges.
3. Caching. Textconv caching can speed up repeated diffs, such as those
you might trigger by running `git log -p`.
Marking files as binary
^^^^^^^^^^^^^^^^^^^^^^^

View File

@@ -319,14 +319,14 @@ top `/`;;
The magic word `top` (mnemonic: `/`) makes the pattern match
from the root of the working tree, even when you are running
the command from inside a subdirectory.
icase;;
The magic word `icase` (there is no mnemonic for it) makes the
pattern match case insensitively. E.g. `:(icase)makefile` matches
both `Makefile` and `makefile`.
--
+
It is envisioned that we will support more types of magic in later
Currently only the slash `/` is recognized as the "magic signature",
but it is envisioned that we will support more types of magic in later
versions of git.
+
A pathspec with only a colon means "there is no pathspec". This form
should not be combined with other pathspec.
[[def_parent]]parent::
A <<def_commit_object,commit object>> contains a (possibly empty) list

View File

@@ -16,6 +16,16 @@ merge.defaultToUpstream::
to their corresponding remote tracking branches, and the tips of
these tracking branches are merged.
merge.ff::
By default, git does not create an extra merge commit when merging
a commit that is a descendant of the current commit. Instead, the
tip of the current branch is fast-forwarded. When set to `false`,
this variable tells git to create an extra merge commit in such
a case (equivalent to giving the `--no-ff` option from the command
line). When set to `only`, only such fast-forward merges are
allowed (equivalent to giving the `--ff-only` option from the
command line).
merge.log::
In addition to branch names, populate the log message with at
most the specified number of one-line descriptions from the

View File

@@ -19,6 +19,11 @@ configuration (see linkgit:git-config[1]).
This should make "--pretty=oneline" a whole lot more readable for
people using 80-column terminals.
--no-abbrev-commit::
Show the full 40-byte hexadecimal commit object name. This negates
`--abbrev-commit` and those options which imply it such as
"--oneline". It also overrides the 'log.abbrevCommit' variable.
--oneline::
This is a shorthand for "--pretty=oneline --abbrev-commit"
used together.

View File

@@ -139,6 +139,10 @@ parents) and `--max-parents=-1` (negative numbers denote no upper limit).
is automatically prepended if missing. If pattern lacks '?', '*',
or '[', '/*' at the end is implied.
--ignore-missing::
Upon seeing an invalid object name in the input, pretend as if
the bad input was not given.
ifndef::git-rev-list[]
--bisect::
@@ -730,7 +734,10 @@ ifdef::git-rev-list[]
Print a number stating how many commits would have been
listed, and suppress all other output. When used together
with '--left-right', instead print the counts for left and
right commits, separated by a tab.
right commits, separated by a tab. When used together with
'--cherry-mark', omit patch equivalent commits from these
counts and print the count for equivalent commits separated
by a tab.
endif::git-rev-list[]

View File

@@ -32,7 +32,7 @@ Calling sequence
* As you find different pairs of files, call `diff_change()` to feed
modified files, `diff_addremove()` to feed created or deleted files,
or `diff_unmerged()` to feed a file whose state is 'unmerged' to the
or `diff_unmerge()` to feed a file whose state is 'unmerged' to the
API. These are thin wrappers to a lower-level `diff_queue()` function
that is flexible enough to record any of these kinds of changes.
@@ -50,7 +50,7 @@ Data structures
This is the internal representation for a single file (blob). It
records the blob object name (if known -- for a work tree file it
typically is a NUL SHA-1), filemode and pathname. This is what the
`diff_addremove()`, `diff_change()` and `diff_unmerged()` synthesize and
`diff_addremove()`, `diff_change()` and `diff_unmerge()` synthesize and
feed `diff_queue()` function with.
* `struct diff_filepair`

View File

@@ -1,7 +1,7 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
DEF_VER=v1.7.5
DEF_VER=v1.7.5.GIT
LF='
'

511
LGPL-2.1 Normal file
View File

@@ -0,0 +1,511 @@
While most of this project is under the GPL (see COPYING), the xdiff/
library and some libc code from compat/ are licensed under the
GNU LGPL, version 2.1 or (at your option) any later version and some
other files are under other licenses. Check the individual files to
be sure.
----------------------------------------
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@@ -24,6 +24,12 @@ all::
# Define NO_OPENSSL environment variable if you do not have OpenSSL.
# This also implies BLK_SHA1.
#
# Define USE_LIBPCRE if you have and want to use libpcre. git-grep will be
# able to use Perl-compatible regular expressions.
#
# Define LIBPCREDIR=/foo/bar if your libpcre header and library files are in
# /foo/bar/include and /foo/bar/lib directories.
#
# Define NO_CURL if you do not have libcurl installed. git-http-pull and
# git-http-push are not built, and you cannot use http:// and https://
# transports.
@@ -70,6 +76,9 @@ all::
# Define NO_FNMATCH_CASEFOLD if your fnmatch function doesn't have the
# FNM_CASEFOLD GNU extension.
#
# Define NO_GECOS_IN_PWENT if you don't have pw_gecos in struct passwd
# in the C library.
#
# Define NO_LIBGEN_H if you don't have libgen.h.
#
# Define NEEDS_LIBGEN if your libgen needs -lgen when linking
@@ -277,8 +286,7 @@ STRIP ?= strip
# mandir
# infodir
# htmldir
# ETC_GITCONFIG (but not sysconfdir)
# ETC_GITATTRIBUTES
# sysconfdir
# can be specified as a relative path some/where/else;
# this is interpreted as relative to $(prefix) and "git" at
# runtime figures out where they are based on the path to the executable.
@@ -294,15 +302,8 @@ sharedir = $(prefix)/share
gitwebdir = $(sharedir)/gitweb
template_dir = share/git-core/templates
htmldir = share/doc/git-doc
ifeq ($(prefix),/usr)
sysconfdir = /etc
ETC_GITCONFIG = $(sysconfdir)/gitconfig
ETC_GITATTRIBUTES = $(sysconfdir)/gitattributes
else
sysconfdir = $(prefix)/etc
ETC_GITCONFIG = etc/gitconfig
ETC_GITATTRIBUTES = etc/gitattributes
endif
lib = lib
# DESTDIR=
pathsep = :
@@ -384,6 +385,7 @@ SCRIPT_LIB += git-rebase--am
SCRIPT_LIB += git-rebase--interactive
SCRIPT_LIB += git-rebase--merge
SCRIPT_LIB += git-sh-setup
SCRIPT_LIB += git-sh-i18n
SCRIPT_PERL += git-add--interactive.perl
SCRIPT_PERL += git-difftool.perl
@@ -417,6 +419,7 @@ PROGRAM_OBJS += shell.o
PROGRAM_OBJS += show-index.o
PROGRAM_OBJS += upload-pack.o
PROGRAM_OBJS += http-backend.o
PROGRAM_OBJS += sh-i18n--envsubst.o
PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS))
@@ -426,8 +429,10 @@ TEST_PROGRAMS_NEED_X += test-date
TEST_PROGRAMS_NEED_X += test-delta
TEST_PROGRAMS_NEED_X += test-dump-cache-tree
TEST_PROGRAMS_NEED_X += test-genrandom
TEST_PROGRAMS_NEED_X += test-index-version
TEST_PROGRAMS_NEED_X += test-line-buffer
TEST_PROGRAMS_NEED_X += test-match-trees
TEST_PROGRAMS_NEED_X += test-mktemp
TEST_PROGRAMS_NEED_X += test-obj-pool
TEST_PROGRAMS_NEED_X += test-parse-options
TEST_PROGRAMS_NEED_X += test-path-utils
@@ -438,8 +443,6 @@ TEST_PROGRAMS_NEED_X += test-string-pool
TEST_PROGRAMS_NEED_X += test-subprocess
TEST_PROGRAMS_NEED_X += test-svn-fe
TEST_PROGRAMS_NEED_X += test-treap
TEST_PROGRAMS_NEED_X += test-index-version
TEST_PROGRAMS_NEED_X += test-mktemp
TEST_PROGRAMS = $(patsubst %,%$X,$(TEST_PROGRAMS_NEED_X))
@@ -551,10 +554,12 @@ LIB_H += rerere.h
LIB_H += resolve-undo.h
LIB_H += revision.h
LIB_H += run-command.h
LIB_H += sha1-array.h
LIB_H += sha1-lookup.h
LIB_H += sideband.h
LIB_H += sigchain.h
LIB_H += strbuf.h
LIB_H += streaming.h
LIB_H += string-list.h
LIB_H += submodule.h
LIB_H += tag.h
@@ -653,6 +658,7 @@ LIB_OBJS += revision.o
LIB_OBJS += run-command.o
LIB_OBJS += server-info.o
LIB_OBJS += setup.o
LIB_OBJS += sha1-array.o
LIB_OBJS += sha1-lookup.o
LIB_OBJS += sha1_file.o
LIB_OBJS += sha1_name.o
@@ -660,6 +666,7 @@ LIB_OBJS += shallow.o
LIB_OBJS += sideband.o
LIB_OBJS += sigchain.o
LIB_OBJS += strbuf.o
LIB_OBJS += streaming.o
LIB_OBJS += string-list.o
LIB_OBJS += submodule.o
LIB_OBJS += symlinks.o
@@ -1099,6 +1106,7 @@ ifeq ($(uname_S),Windows)
BLK_SHA1 = YesPlease
NO_POSIX_GOODIES = UnfortunatelyYes
NATIVE_CRLF = YesPlease
NO_D_INO_IN_DIRENT = YesPlease
CC = compat/vcbuild/scripts/clink.pl
AR = compat/vcbuild/scripts/lib.pl
@@ -1174,6 +1182,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
NO_INET_PTON = YesPlease
NO_INET_NTOP = YesPlease
NO_POSIX_GOODIES = UnfortunatelyYes
NO_D_INO_IN_DIRENT = YesPlease
COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/win32
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
COMPAT_OBJS += compat/mingw.o compat/winansi.o \
@@ -1198,6 +1207,14 @@ endif
-include config.mak.autogen
-include config.mak
ifndef sysconfdir
ifeq ($(prefix),/usr)
sysconfdir = /etc
else
sysconfdir = etc
endif
endif
ifdef CHECK_HEADER_DEPENDENCIES
COMPUTE_HEADER_DEPENDENCIES =
USE_COMPUTED_HEADER_DEPENDENCIES =
@@ -1254,6 +1271,15 @@ ifdef NO_LIBGEN_H
COMPAT_OBJS += compat/basename.o
endif
ifdef USE_LIBPCRE
BASIC_CFLAGS += -DUSE_LIBPCRE
ifdef LIBPCREDIR
BASIC_CFLAGS += -I$(LIBPCREDIR)/include
EXTLIBS += -L$(LIBPCREDIR)/$(lib) $(CC_LD_DYNPATH)$(LIBPCREDIR)/$(lib)
endif
EXTLIBS += -lpcre
endif
ifdef NO_CURL
BASIC_CFLAGS += -DNO_CURL
REMOTE_CURL_PRIMARY =
@@ -1683,7 +1709,9 @@ strip: $(PROGRAMS) git$X
git.o: common-cmds.h
git.sp git.s git.o: EXTRA_CPPFLAGS = -DGIT_VERSION='"$(GIT_VERSION)"' \
'-DGIT_HTML_PATH="$(htmldir_SQ)"'
'-DGIT_HTML_PATH="$(htmldir_SQ)"' \
'-DGIT_MAN_PATH="$(mandir_SQ)"' \
'-DGIT_INFO_PATH="$(infodir_SQ)"'
git$X: git.o $(BUILTIN_OBJS) $(GITLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ git.o \
@@ -1754,33 +1782,7 @@ $(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl
gitweb:
$(QUIET_SUBDIR0)gitweb $(QUIET_SUBDIR1) all
ifdef JSMIN
GITWEB_PROGRAMS += gitweb/static/gitweb.min.js
GITWEB_JS = gitweb/static/gitweb.min.js
else
GITWEB_JS = gitweb/static/gitweb.js
endif
ifdef CSSMIN
GITWEB_PROGRAMS += gitweb/static/gitweb.min.css
GITWEB_CSS = gitweb/static/gitweb.min.css
else
GITWEB_CSS = gitweb/static/gitweb.css
endif
OTHER_PROGRAMS += gitweb/gitweb.cgi $(GITWEB_PROGRAMS)
gitweb/gitweb.cgi: gitweb/gitweb.perl $(GITWEB_PROGRAMS)
$(QUIET_SUBDIR0)gitweb $(QUIET_SUBDIR1) $(patsubst gitweb/%,%,$@)
ifdef JSMIN
gitweb/static/gitweb.min.js: gitweb/static/gitweb.js
$(QUIET_SUBDIR0)gitweb $(QUIET_SUBDIR1) $(patsubst gitweb/%,%,$@)
endif # JSMIN
ifdef CSSMIN
gitweb/static/gitweb.min.css: gitweb/static/gitweb.css
$(QUIET_SUBDIR0)gitweb $(QUIET_SUBDIR1) $(patsubst gitweb/%,%,$@)
endif # CSSMIN
git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/static/gitweb.css gitweb/static/gitweb.js
git-instaweb: git-instaweb.sh gitweb
$(QUIET_GEN)$(RM) $@ $@+ && \
sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
-e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
@@ -2066,10 +2068,14 @@ XGETTEXT_FLAGS = \
--from-code=UTF-8
XGETTEXT_FLAGS_C = $(XGETTEXT_FLAGS) --language=C \
--keyword=_ --keyword=N_ --keyword="Q_:1,2"
XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) --language=Shell
LOCALIZED_C := $(C_OBJ:o=c)
LOCALIZED_SH := $(SCRIPT_SH)
po/git.pot: $(LOCALIZED_C)
$(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ $(XGETTEXT_FLAGS_C) $(LOCALIZED_C) && \
$(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ $(XGETTEXT_FLAGS_C) $(LOCALIZED_C)
$(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ --join-existing $(XGETTEXT_FLAGS_SH) \
$(LOCALIZED_SH)
mv $@+ $@
pot: po/git.pot
@@ -2107,6 +2113,7 @@ GIT-BUILD-OPTIONS: FORCE
@echo PYTHON_PATH=\''$(subst ','\'',$(PYTHON_PATH_SQ))'\' >>$@
@echo TAR=\''$(subst ','\'',$(subst ','\'',$(TAR)))'\' >>$@
@echo NO_CURL=\''$(subst ','\'',$(subst ','\'',$(NO_CURL)))'\' >>$@
@echo USE_LIBPCRE=\''$(subst ','\'',$(subst ','\'',$(USE_LIBPCRE)))'\' >>$@
@echo NO_PERL=\''$(subst ','\'',$(subst ','\'',$(NO_PERL)))'\' >>$@
@echo NO_PYTHON=\''$(subst ','\'',$(subst ','\'',$(NO_PYTHON)))'\' >>$@
ifdef GIT_TEST_CMP

View File

@@ -1 +1 @@
Documentation/RelNotes/1.7.5.txt
Documentation/RelNotes/1.7.6.txt

View File

@@ -40,7 +40,7 @@ const char *real_path(const char *path)
while (depth--) {
if (!is_directory(buf)) {
char *last_slash = strrchr(buf, '/');
char *last_slash = find_last_dir_sep(buf);
if (last_slash) {
*last_slash = '\0';
last_elem = xstrdup(last_slash + 1);
@@ -65,7 +65,7 @@ const char *real_path(const char *path)
if (len + strlen(last_elem) + 2 > PATH_MAX)
die ("Too long path name: '%s/%s'",
buf, last_elem);
if (len && buf[len-1] != '/')
if (len && !is_dir_sep(buf[len-1]))
buf[len++] = '/';
strcpy(buf + len, last_elem);
free(last_elem);

View File

@@ -9,13 +9,7 @@
#include "run-command.h"
#include "log-tree.h"
#include "bisect.h"
struct sha1_array {
unsigned char (*sha1)[20];
int sha1_nr;
int sha1_alloc;
int sorted;
};
#include "sha1-array.h"
static struct sha1_array good_revs;
static struct sha1_array skipped_revs;
@@ -425,22 +419,15 @@ static void argv_array_push_sha1(struct argv_array *array,
argv_array_push(array, strbuf_detach(&buf, NULL));
}
static void sha1_array_push(struct sha1_array *array,
const unsigned char *sha1)
{
ALLOC_GROW(array->sha1, array->sha1_nr + 1, array->sha1_alloc);
hashcpy(array->sha1[array->sha1_nr++], sha1);
}
static int register_ref(const char *refname, const unsigned char *sha1,
int flags, void *cb_data)
{
if (!strcmp(refname, "bad")) {
current_bad_sha1 = sha1;
} else if (!prefixcmp(refname, "good-")) {
sha1_array_push(&good_revs, sha1);
sha1_array_append(&good_revs, sha1);
} else if (!prefixcmp(refname, "skip-")) {
sha1_array_push(&skipped_revs, sha1);
sha1_array_append(&skipped_revs, sha1);
}
return 0;
@@ -477,41 +464,14 @@ static void read_bisect_paths(struct argv_array *array)
fclose(fp);
}
static int array_cmp(const void *a, const void *b)
{
return hashcmp(a, b);
}
static void sort_sha1_array(struct sha1_array *array)
{
qsort(array->sha1, array->sha1_nr, sizeof(*array->sha1), array_cmp);
array->sorted = 1;
}
static const unsigned char *sha1_access(size_t index, void *table)
{
unsigned char (*array)[20] = table;
return array[index];
}
static int lookup_sha1_array(struct sha1_array *array,
const unsigned char *sha1)
{
if (!array->sorted)
sort_sha1_array(array);
return sha1_pos(sha1, array->sha1, array->sha1_nr, sha1_access);
}
static char *join_sha1_array_hex(struct sha1_array *array, char delim)
{
struct strbuf joined_hexs = STRBUF_INIT;
int i;
for (i = 0; i < array->sha1_nr; i++) {
for (i = 0; i < array->nr; i++) {
strbuf_addstr(&joined_hexs, sha1_to_hex(array->sha1[i]));
if (i + 1 < array->sha1_nr)
if (i + 1 < array->nr)
strbuf_addch(&joined_hexs, delim);
}
@@ -546,13 +506,13 @@ struct commit_list *filter_skipped(struct commit_list *list,
if (count)
*count = 0;
if (!skipped_revs.sha1_nr)
if (!skipped_revs.nr)
return list;
while (list) {
struct commit_list *next = list->next;
list->next = NULL;
if (0 <= lookup_sha1_array(&skipped_revs,
if (0 <= sha1_array_lookup(&skipped_revs,
list->item->object.sha1)) {
if (skipped_first && !*skipped_first)
*skipped_first = 1;
@@ -647,7 +607,7 @@ static struct commit_list *managed_skipped(struct commit_list *list,
*tried = NULL;
if (!skipped_revs.sha1_nr)
if (!skipped_revs.nr)
return list;
list = filter_skipped(list, tried, 0, &count, &skipped_first);
@@ -672,7 +632,7 @@ static void bisect_rev_setup(struct rev_info *revs, const char *prefix,
/* rev_argv.argv[0] will be ignored by setup_revisions */
argv_array_push(&rev_argv, xstrdup("bisect_rev_setup"));
argv_array_push_sha1(&rev_argv, current_bad_sha1, bad_format);
for (i = 0; i < good_revs.sha1_nr; i++)
for (i = 0; i < good_revs.nr; i++)
argv_array_push_sha1(&rev_argv, good_revs.sha1[i],
good_format);
argv_array_push(&rev_argv, xstrdup("--"));
@@ -772,12 +732,12 @@ static struct commit *get_commit_reference(const unsigned char *sha1)
static struct commit **get_bad_and_good_commits(int *rev_nr)
{
int len = 1 + good_revs.sha1_nr;
int len = 1 + good_revs.nr;
struct commit **rev = xmalloc(len * sizeof(*rev));
int i, n = 0;
rev[n++] = get_commit_reference(current_bad_sha1);
for (i = 0; i < good_revs.sha1_nr; i++)
for (i = 0; i < good_revs.nr; i++)
rev[n++] = get_commit_reference(good_revs.sha1[i]);
*rev_nr = n;
@@ -840,9 +800,9 @@ static void check_merge_bases(void)
const unsigned char *mb = result->item->object.sha1;
if (!hashcmp(mb, current_bad_sha1)) {
handle_bad_merge_base();
} else if (0 <= lookup_sha1_array(&good_revs, mb)) {
} else if (0 <= sha1_array_lookup(&good_revs, mb)) {
continue;
} else if (0 <= lookup_sha1_array(&skipped_revs, mb)) {
} else if (0 <= sha1_array_lookup(&skipped_revs, mb)) {
handle_skipped_merge_base(mb);
} else {
printf("Bisecting: a merge base must be tested\n");
@@ -903,7 +863,7 @@ static void check_good_are_ancestors_of_bad(const char *prefix)
return;
/* Bisecting with no good rev is ok. */
if (good_revs.sha1_nr == 0)
if (good_revs.nr == 0)
return;
/* Check if all good revs are ancestor of the bad rev. */
@@ -968,7 +928,7 @@ int bisect_next_all(const char *prefix)
bisect_common(&revs);
revs.commits = find_bisection(revs.commits, &reaches, &all,
!!skipped_revs.sha1_nr);
!!skipped_revs.nr);
revs.commits = managed_skipped(revs.commits, &tried);
if (!revs.commits) {

View File

@@ -26,6 +26,27 @@ struct update_callback_data {
int add_errors;
};
static int fix_unmerged_status(struct diff_filepair *p,
struct update_callback_data *data)
{
if (p->status != DIFF_STATUS_UNMERGED)
return p->status;
if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL) && !p->two->mode)
/*
* This is not an explicit add request, and the
* path is missing from the working tree (deleted)
*/
return DIFF_STATUS_DELETED;
else
/*
* Either an explicit add request, or path exists
* in the working tree. An attempt to explicitly
* add a path that does not exist in the working tree
* will be caught as an error by the caller immediately.
*/
return DIFF_STATUS_MODIFIED;
}
static void update_callback(struct diff_queue_struct *q,
struct diff_options *opt, void *cbdata)
{
@@ -35,30 +56,9 @@ static void update_callback(struct diff_queue_struct *q,
for (i = 0; i < q->nr; i++) {
struct diff_filepair *p = q->queue[i];
const char *path = p->one->path;
switch (p->status) {
switch (fix_unmerged_status(p, data)) {
default:
die(_("unexpected diff status %c"), p->status);
case DIFF_STATUS_UNMERGED:
/*
* ADD_CACHE_IGNORE_REMOVAL is unset if "git
* add -u" is calling us, In such a case, a
* missing work tree file needs to be removed
* if there is an unmerged entry at stage #2,
* but such a diff record is followed by
* another with DIFF_STATUS_DELETED (and if
* there is no stage #2, we won't see DELETED
* nor MODIFIED). We can simply continue
* either way.
*/
if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL))
continue;
/*
* Otherwise, it is "git add path" is asking
* to explicitly add it; we fall through. A
* missing work tree file is an error and is
* caught by add_file_to_index() in such a
* case.
*/
case DIFF_STATUS_MODIFIED:
case DIFF_STATUS_TYPE_CHANGED:
if (add_file_to_index(&the_index, path, data->flags)) {
@@ -91,6 +91,7 @@ int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
data.flags = flags;
data.add_errors = 0;
rev.diffopt.format_callback_data = &data;
rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
return !!data.add_errors;
}
@@ -241,7 +242,7 @@ int run_add_interactive(const char *revision, const char *patch_mode,
return status;
}
int interactive_add(int argc, const char **argv, const char *prefix)
int interactive_add(int argc, const char **argv, const char *prefix, int patch)
{
const char **pathspec = NULL;
@@ -252,7 +253,7 @@ int interactive_add(int argc, const char **argv, const char *prefix)
}
return run_add_interactive(NULL,
patch_interactive ? "--patch" : NULL,
patch ? "--patch" : NULL,
pathspec);
}
@@ -331,8 +332,8 @@ static struct option builtin_add_options[] = {
static int add_config(const char *var, const char *value, void *cb)
{
if (!strcasecmp(var, "add.ignoreerrors") ||
!strcasecmp(var, "add.ignore-errors")) {
if (!strcmp(var, "add.ignoreerrors") ||
!strcmp(var, "add.ignore-errors")) {
ignore_add_errors = git_config_bool(var, value);
return 0;
}
@@ -378,7 +379,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
if (patch_interactive)
add_interactive = 1;
if (add_interactive)
exit(interactive_add(argc - 1, argv + 1, prefix));
exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
if (edit_interactive)
return(edit_patch(argc, argv, prefix));

View File

@@ -43,6 +43,7 @@ static int apply = 1;
static int apply_in_reverse;
static int apply_with_reject;
static int apply_verbosely;
static int allow_overlap;
static int no_add;
static const char *fake_ancestor;
static int line_termination = '\n';
@@ -2430,9 +2431,9 @@ static void update_image(struct image *img,
memcpy(img->line + applied_pos,
postimage->line,
postimage->nr * sizeof(*img->line));
for (i = 0; i < postimage->nr; i++)
img->line[applied_pos + i].flag |= LINE_PATCHED;
if (!allow_overlap)
for (i = 0; i < postimage->nr; i++)
img->line[applied_pos + i].flag |= LINE_PATCHED;
img->nr = nr;
}
@@ -3889,6 +3890,8 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)
"don't expect at least one line of context"),
OPT_BOOLEAN(0, "reject", &apply_with_reject,
"leave the rejected hunks in corresponding *.rej files"),
OPT_BOOLEAN(0, "allow-overlap", &allow_overlap,
"allow overlapping hunks"),
OPT__VERBOSE(&apply_verbosely, "be verbose"),
OPT_BIT(0, "inaccurate-eof", &options,
"tolerate incorrectly detected missing new-line at the end of file",

View File

@@ -1378,7 +1378,7 @@ static void get_ac_line(const char *inbuf, const char *what,
timepos = tmp;
*tmp = 0;
while (person < tmp && *tmp != ' ')
while (person < tmp && !(*tmp == ' ' && tmp[1] == '<'))
tmp--;
if (tmp <= person)
return;
@@ -1484,13 +1484,14 @@ static void write_filename_info(const char *path)
/*
* Porcelain/Incremental format wants to show a lot of details per
* commit. Instead of repeating this every line, emit it only once,
* the first time each commit appears in the output.
* the first time each commit appears in the output (unless the
* user has specifically asked for us to repeat).
*/
static int emit_one_suspect_detail(struct origin *suspect)
static int emit_one_suspect_detail(struct origin *suspect, int repeat)
{
struct commit_info ci;
if (suspect->commit->object.flags & METAINFO_SHOWN)
if (!repeat && (suspect->commit->object.flags & METAINFO_SHOWN))
return 0;
suspect->commit->object.flags |= METAINFO_SHOWN;
@@ -1529,7 +1530,7 @@ static void found_guilty_entry(struct blame_entry *ent)
printf("%s %d %d %d\n",
sha1_to_hex(suspect->commit->object.sha1),
ent->s_lno + 1, ent->lno + 1, ent->num_lines);
emit_one_suspect_detail(suspect);
emit_one_suspect_detail(suspect, 0);
write_filename_info(suspect->path);
maybe_flush_or_die(stdout, "stdout");
}
@@ -1618,9 +1619,19 @@ static const char *format_time(unsigned long time, const char *tz_str,
#define OUTPUT_SHOW_SCORE 0100
#define OUTPUT_NO_AUTHOR 0200
#define OUTPUT_SHOW_EMAIL 0400
#define OUTPUT_LINE_PORCELAIN 01000
static void emit_porcelain(struct scoreboard *sb, struct blame_entry *ent)
static void emit_porcelain_details(struct origin *suspect, int repeat)
{
if (emit_one_suspect_detail(suspect, repeat) ||
(suspect->commit->object.flags & MORE_THAN_ONE_PATH))
write_filename_info(suspect->path);
}
static void emit_porcelain(struct scoreboard *sb, struct blame_entry *ent,
int opt)
{
int repeat = opt & OUTPUT_LINE_PORCELAIN;
int cnt;
const char *cp;
struct origin *suspect = ent->suspect;
@@ -1633,17 +1644,18 @@ static void emit_porcelain(struct scoreboard *sb, struct blame_entry *ent)
ent->s_lno + 1,
ent->lno + 1,
ent->num_lines);
if (emit_one_suspect_detail(suspect) ||
(suspect->commit->object.flags & MORE_THAN_ONE_PATH))
write_filename_info(suspect->path);
emit_porcelain_details(suspect, repeat);
cp = nth_line(sb, ent->lno);
for (cnt = 0; cnt < ent->num_lines; cnt++) {
char ch;
if (cnt)
if (cnt) {
printf("%s %d %d\n", hex,
ent->s_lno + 1 + cnt,
ent->lno + 1 + cnt);
if (repeat)
emit_porcelain_details(suspect, 1);
}
putchar('\t');
do {
ch = *cp++;
@@ -1756,7 +1768,7 @@ static void output(struct scoreboard *sb, int option)
for (ent = sb->ent; ent; ent = ent->next) {
if (option & OUTPUT_PORCELAIN)
emit_porcelain(sb, ent);
emit_porcelain(sb, ent, option);
else {
emit_other(sb, ent, option);
}
@@ -2300,6 +2312,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
OPT_BIT('f', "show-name", &output_option, "Show original filename (Default: auto)", OUTPUT_SHOW_NAME),
OPT_BIT('n', "show-number", &output_option, "Show original linenumber (Default: off)", OUTPUT_SHOW_NUMBER),
OPT_BIT('p', "porcelain", &output_option, "Show in a format designed for machine consumption", OUTPUT_PORCELAIN),
OPT_BIT(0, "line-porcelain", &output_option, "Show porcelain format with per-line commit information", OUTPUT_PORCELAIN|OUTPUT_LINE_PORCELAIN),
OPT_BIT('c', NULL, &output_option, "Use the same output mode as git-annotate (Default: off)", OUTPUT_ANNOTATE_COMPAT),
OPT_BIT('t', NULL, &output_option, "Show raw timestamp (Default: off)", OUTPUT_RAW_TIMESTAMP),
OPT_BIT('l', NULL, &output_option, "Show long commit SHA1 (Default: off)", OUTPUT_LONG_OBJECT_NAME),

View File

@@ -399,9 +399,7 @@ static void add_verbose_info(struct strbuf *out, struct ref_item *item,
struct commit *commit = item->commit;
if (commit && !parse_commit(commit)) {
struct pretty_print_context ctx = {0};
pretty_print_commit(CMIT_FMT_ONELINE, commit,
&subject, &ctx);
pp_commit_easy(CMIT_FMT_ONELINE, commit, &subject);
sub = subject.buf;
}

View File

@@ -306,9 +306,8 @@ static void show_local_changes(struct object *head, struct diff_options *opts)
static void describe_detached_head(const char *msg, struct commit *commit)
{
struct strbuf sb = STRBUF_INIT;
struct pretty_print_context ctx = {0};
parse_commit(commit);
pretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, &ctx);
pp_commit_easy(CMIT_FMT_ONELINE, commit, &sb);
fprintf(stderr, "%s %s... %s\n", msg,
find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV), sb.buf);
strbuf_release(&sb);
@@ -623,14 +622,12 @@ static int clear_commit_marks_from_one_ref(const char *refname,
static void describe_one_orphan(struct strbuf *sb, struct commit *commit)
{
struct pretty_print_context ctx = { 0 };
parse_commit(commit);
strbuf_addstr(sb, " ");
strbuf_addstr(sb,
find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV));
strbuf_addch(sb, ' ');
pretty_print_commit(CMIT_FMT_ONELINE, commit, sb, &ctx);
pp_commit_easy(CMIT_FMT_ONELINE, commit, sb);
strbuf_addch(sb, '\n');
}
@@ -660,24 +657,25 @@ static void suggest_reattach(struct commit *commit, struct rev_info *revs)
"Warning: you are leaving %d commit behind, "
"not connected to\n"
"any of your branches:\n\n"
"%s\n"
"If you want to keep it by creating a new branch, "
"this may be a good time\nto do so with:\n\n"
" git branch new_branch_name %s\n\n",
"%s\n",
/* The plural version */
"Warning: you are leaving %d commits behind, "
"not connected to\n"
"any of your branches:\n\n"
"%s\n"
"If you want to keep them by creating a new branch, "
"this may be a good time\nto do so with:\n\n"
" git branch new_branch_name %s\n\n",
"%s\n",
/* Give ngettext() the count */
lost),
lost,
sb.buf,
sha1_to_hex(commit->object.sha1));
sb.buf);
strbuf_release(&sb);
if (advice_detached_head)
fprintf(stderr,
_(
"If you want to keep them by creating a new branch, "
"this may be a good time\nto do so with:\n\n"
" git branch new_branch_name %s\n\n"),
sha1_to_hex(commit->object.sha1));
}
/*

View File

@@ -81,7 +81,7 @@ static struct option builtin_clone_options[] = {
"path to git-upload-pack on the remote"),
OPT_STRING(0, "depth", &option_depth, "depth",
"create a shallow clone of that depth"),
OPT_STRING('L', "separate-git-dir", &real_git_dir, "gitdir",
OPT_STRING(0, "separate-git-dir", &real_git_dir, "gitdir",
"separate git dir from working tree"),
OPT_END()

View File

@@ -83,7 +83,7 @@ static const char *template_file;
static const char *author_message, *author_message_buffer;
static char *edit_message, *use_message;
static char *fixup_message, *squash_message;
static int all, edit_flag, also, interactive, only, amend, signoff;
static int all, edit_flag, also, interactive, patch_interactive, only, amend, signoff;
static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
static int no_post_rewrite, allow_empty_message;
static char *untracked_files_arg, *force_date, *ignore_submodule_arg;
@@ -152,6 +152,7 @@ static struct option builtin_commit_options[] = {
OPT_BOOLEAN('a', "all", &all, "commit all changed files"),
OPT_BOOLEAN('i', "include", &also, "add specified files to index for commit"),
OPT_BOOLEAN(0, "interactive", &interactive, "interactively add files"),
OPT_BOOLEAN('p', "patch", &patch_interactive, "interactively add changes"),
OPT_BOOLEAN('o', "only", &only, "commit only specified files"),
OPT_BOOLEAN('n', "no-verify", &no_verify, "bypass pre-commit hook"),
OPT_BOOLEAN(0, "dry-run", &dry_run, "show what would be committed"),
@@ -336,18 +337,11 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, int
int fd;
struct string_list partial;
const char **pathspec = NULL;
char *old_index_env = NULL;
int refresh_flags = REFRESH_QUIET;
if (is_status)
refresh_flags |= REFRESH_UNMERGED;
if (interactive) {
if (interactive_add(argc, argv, prefix) != 0)
die(_("interactive add failed"));
if (read_cache_preload(NULL) < 0)
die(_("index file corrupt"));
commit_style = COMMIT_AS_IS;
return get_index_file();
}
if (*argv)
pathspec = get_pathspec(prefix, argv);
@@ -355,6 +349,33 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, int
if (read_cache_preload(pathspec) < 0)
die(_("index file corrupt"));
if (interactive) {
fd = hold_locked_index(&index_lock, 1);
refresh_cache_or_die(refresh_flags);
if (write_cache(fd, active_cache, active_nr) ||
close_lock_file(&index_lock))
die(_("unable to create temporary index"));
old_index_env = getenv(INDEX_ENVIRONMENT);
setenv(INDEX_ENVIRONMENT, index_lock.filename, 1);
if (interactive_add(argc, argv, prefix, patch_interactive) != 0)
die(_("interactive add failed"));
if (old_index_env && *old_index_env)
setenv(INDEX_ENVIRONMENT, old_index_env, 1);
else
unsetenv(INDEX_ENVIRONMENT);
discard_cache();
read_cache_from(index_lock.filename);
commit_style = COMMIT_NORMAL;
return index_lock.filename;
}
/*
* Non partial, non as-is commit.
*
@@ -615,6 +636,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
const char *hook_arg1 = NULL;
const char *hook_arg2 = NULL;
int ident_shown = 0;
int clean_message_contents = (cleanup_mode != CLEANUP_NONE);
if (!no_verify && run_hook(index_file, "pre-commit", NULL))
return 0;
@@ -681,6 +703,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
if (strbuf_read_file(&sb, template_file, 0) < 0)
die_errno(_("could not read '%s'"), template_file);
hook_arg1 = "template";
clean_message_contents = 0;
}
/*
@@ -708,7 +731,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
if (s->fp == NULL)
die_errno(_("could not open '%s'"), git_path(commit_editmsg));
if (cleanup_mode != CLEANUP_NONE)
if (clean_message_contents)
stripspace(&sb, 0);
if (signoff) {
@@ -1041,8 +1064,11 @@ static int parse_and_validate_options(int argc, const char *argv[],
author_message_buffer = read_commit_message(author_message);
}
if (patch_interactive)
interactive = 1;
if (!!also + !!only + !!all + !!interactive > 1)
die(_("Only one of --include/--only/--all/--interactive can be used."));
die(_("Only one of --include/--only/--all/--interactive/--patch can be used."));
if (argc == 0 && (also || (only && !amend)))
die(_("No paths with --include/--only does not make sense."));
if (argc == 0 && only && amend)
@@ -1064,8 +1090,6 @@ static int parse_and_validate_options(int argc, const char *argv[],
if (all && argc > 0)
die(_("Paths with -a does not make sense."));
else if (interactive && argc > 0)
die(_("Paths with --interactive does not make sense."));
if (null_termination && status_format == STATUS_FORMAT_LONG)
status_format = STATUS_FORMAT_PORCELAIN;
@@ -1183,9 +1207,6 @@ int cmd_status(int argc, const char **argv, const char *prefix)
if (argc == 2 && !strcmp(argv[1], "-h"))
usage_with_options(builtin_status_usage, builtin_status_options);
if (null_termination && status_format == STATUS_FORMAT_LONG)
status_format = STATUS_FORMAT_PORCELAIN;
wt_status_prepare(&s);
gitmodules_config();
git_config(git_status_config, &s);
@@ -1193,6 +1214,10 @@ int cmd_status(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix,
builtin_status_options,
builtin_status_usage, 0);
if (null_termination && status_format == STATUS_FORMAT_LONG)
status_format = STATUS_FORMAT_PORCELAIN;
handle_untracked_files_arg(&s);
if (show_ignored_in_status)
s.show_ignored_files = 1;

View File

@@ -436,9 +436,14 @@ int cmd_config(int argc, const char **argv, const char *prefix)
NULL, NULL);
}
else if (actions == ACTION_SET) {
int ret;
check_argc(argc, 2, 2);
value = normalize_value(argv[0], argv[1]);
return git_config_set(argv[0], value);
ret = git_config_set(argv[0], value);
if (ret == CONFIG_NOTHING_SET)
error("cannot overwrite multiple values with a single value\n"
" Use a regexp, --add or --set-all to change %s.", argv[0]);
return ret;
}
else if (actions == ACTION_SET_ALL) {
check_argc(argc, 2, 3);

View File

@@ -226,7 +226,7 @@ static void insert_one_alternate_ref(const struct ref *ref, void *unused)
static void insert_alternate_refs(void)
{
foreach_alt_odb(refs_from_alternate_cb, insert_one_alternate_ref);
for_each_alternate_ref(insert_one_alternate_ref, NULL);
}
#define INITIAL_FLUSH 16
@@ -472,8 +472,10 @@ static int mark_complete(const char *path, const unsigned char *sha1, int flag,
}
if (o && o->type == OBJ_COMMIT) {
struct commit *commit = (struct commit *)o;
commit->object.flags |= COMPLETE;
commit_list_insert_by_date(commit, &complete);
if (!(commit->object.flags & COMPLETE)) {
commit->object.flags |= COMPLETE;
commit_list_insert_by_date(commit, &complete);
}
}
return 0;
}

View File

@@ -776,6 +776,15 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
int i;
int dummy;
int use_index = 1;
enum {
pattern_type_unspecified = 0,
pattern_type_bre,
pattern_type_ere,
pattern_type_fixed,
pattern_type_pcre,
};
int pattern_type = pattern_type_unspecified;
struct option options[] = {
OPT_BOOLEAN(0, "cached", &cached,
"search in index instead of in the work tree"),
@@ -797,13 +806,18 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
"descend at most <depth> levels", PARSE_OPT_NONEG,
NULL, 1 },
OPT_GROUP(""),
OPT_BIT('E', "extended-regexp", &opt.regflags,
"use extended POSIX regular expressions", REG_EXTENDED),
OPT_NEGBIT('G', "basic-regexp", &opt.regflags,
"use basic POSIX regular expressions (default)",
REG_EXTENDED),
OPT_BOOLEAN('F', "fixed-strings", &opt.fixed,
"interpret patterns as fixed strings"),
OPT_SET_INT('E', "extended-regexp", &pattern_type,
"use extended POSIX regular expressions",
pattern_type_ere),
OPT_SET_INT('G', "basic-regexp", &pattern_type,
"use basic POSIX regular expressions (default)",
pattern_type_bre),
OPT_SET_INT('F', "fixed-strings", &pattern_type,
"interpret patterns as fixed strings",
pattern_type_fixed),
OPT_SET_INT('P', "perl-regexp", &pattern_type,
"use Perl-compatible regular expressions",
pattern_type_pcre),
OPT_GROUP(""),
OPT_BOOLEAN('n', "line-number", &opt.linenum, "show line numbers"),
OPT_NEGBIT('h', NULL, &opt.pathname, "don't show filenames", 1),
@@ -909,6 +923,28 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
PARSE_OPT_KEEP_DASHDASH |
PARSE_OPT_STOP_AT_NON_OPTION |
PARSE_OPT_NO_INTERNAL_HELP);
switch (pattern_type) {
case pattern_type_fixed:
opt.fixed = 1;
opt.pcre = 0;
break;
case pattern_type_bre:
opt.fixed = 0;
opt.pcre = 0;
opt.regflags &= ~REG_EXTENDED;
break;
case pattern_type_ere:
opt.fixed = 0;
opt.pcre = 0;
opt.regflags |= REG_EXTENDED;
break;
case pattern_type_pcre:
opt.fixed = 0;
opt.pcre = 1;
break;
default:
break; /* nothing */
}
if (use_index && !startup_info->have_repository)
/* die the same way as if we did it at the beginning */
@@ -950,8 +986,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
die(_("no pattern given."));
if (!opt.fixed && opt.ignore_case)
opt.regflags |= REG_ICASE;
if ((opt.regflags != REG_NEWLINE) && opt.fixed)
die(_("cannot mix --fixed-strings and regexp"));
#ifndef NO_PTHREADS
if (online_cpus() == 1 || !grep_threads_ok(&opt))
@@ -994,13 +1028,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
verify_filename(prefix, argv[j]);
}
if (i < argc)
paths = get_pathspec(prefix, argv + i);
else if (prefix) {
paths = xcalloc(2, sizeof(const char *));
paths[0] = prefix;
paths[1] = NULL;
}
paths = get_pathspec(prefix, argv + i);
init_pathspec(&pathspec, paths);
pathspec.max_depth = opt.max_depth;
pathspec.recursive = 1;

View File

@@ -14,8 +14,11 @@ static void hash_fd(int fd, const char *type, int write_object, const char *path
{
struct stat st;
unsigned char sha1[20];
unsigned flags = (HASH_FORMAT_CHECK |
(write_object ? HASH_WRITE_OBJECT : 0));
if (fstat(fd, &st) < 0 ||
index_fd(sha1, fd, &st, write_object, type_from_string(type), path, 1))
index_fd(sha1, fd, &st, type_from_string(type), path, flags))
die(write_object
? "Unable to add %s to database"
: "Unable to hash %s", path);

View File

@@ -491,7 +491,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
"specify that the git repository is to be shared amongst several users",
PARSE_OPT_OPTARG | PARSE_OPT_NONEG, shared_callback, 0},
OPT_BIT('q', "quiet", &flags, "be quiet", INIT_DB_QUIET),
OPT_STRING('L', "separate-git-dir", &real_git_dir, "gitdir",
OPT_STRING(0, "separate-git-dir", &real_git_dir, "gitdir",
"separate git dir from working tree"),
OPT_END()
};

View File

@@ -23,14 +23,18 @@
/* Set a default date-time format for git log ("log.date" config variable) */
static const char *default_date_mode = NULL;
static int default_abbrev_commit;
static int default_show_root = 1;
static int decoration_style;
static int decoration_given;
static const char *fmt_patch_subject_prefix = "PATCH";
static const char *fmt_pretty;
static const char * const builtin_log_usage =
static const char * const builtin_log_usage[] = {
"git log [<options>] [<since>..<until>] [[--] <path>...]\n"
" or: git show [options] <object>...";
" or: git show [options] <object>...",
NULL
};
static int parse_decoration_style(const char *var, const char *value)
{
@@ -49,6 +53,23 @@ static int parse_decoration_style(const char *var, const char *value)
return -1;
}
static int decorate_callback(const struct option *opt, const char *arg, int unset)
{
if (unset)
decoration_style = 0;
else if (arg)
decoration_style = parse_decoration_style("command line", arg);
else
decoration_style = DECORATE_SHORT_REFS;
if (decoration_style < 0)
die("invalid --decorate option: %s", arg);
decoration_given = 1;
return 0;
}
static void cmd_log_init_defaults(struct rev_info *rev)
{
rev->abbrev = DEFAULT_ABBREV;
@@ -57,6 +78,7 @@ static void cmd_log_init_defaults(struct rev_info *rev)
get_commit_format(fmt_pretty, rev);
rev->verbose_header = 1;
DIFF_OPT_SET(&rev->diffopt, RECURSIVE);
rev->abbrev_commit = default_abbrev_commit;
rev->show_root_diff = default_show_root;
rev->subject_prefix = fmt_patch_subject_prefix;
DIFF_OPT_SET(&rev->diffopt, ALLOW_TEXTCONV);
@@ -68,16 +90,29 @@ static void cmd_log_init_defaults(struct rev_info *rev)
static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
struct rev_info *rev, struct setup_revision_opt *opt)
{
int i;
int decoration_given = 0;
struct userformat_want w;
/*
* Check for -h before setup_revisions(), or "git log -h" will
* fail when run without a git directory.
*/
if (argc == 2 && !strcmp(argv[1], "-h"))
usage(builtin_log_usage);
int quiet = 0, source = 0;
const struct option builtin_log_options[] = {
OPT_BOOLEAN(0, "quiet", &quiet, "suppress diff output"),
OPT_BOOLEAN(0, "source", &source, "show source"),
{ OPTION_CALLBACK, 0, "decorate", NULL, NULL, "decorate options",
PARSE_OPT_OPTARG, decorate_callback},
OPT_END()
};
argc = parse_options(argc, argv, prefix,
builtin_log_options, builtin_log_usage,
PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN |
PARSE_OPT_KEEP_DASHDASH);
argc = setup_revisions(argc, argv, rev, opt);
if (quiet)
rev->diffopt.output_format |= DIFF_FORMAT_NO_OUTPUT;
/* Any arguments at this point are not recognized */
if (argc > 1)
die("unrecognized argument: %s", argv[1]);
memset(&w, 0, sizeof(w));
userformat_find_requirements(NULL, &w);
@@ -94,34 +129,20 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
if (rev->diffopt.pathspec.nr != 1)
usage("git logs can only follow renames on one pathname at a time");
}
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
if (!strcmp(arg, "--decorate")) {
decoration_style = DECORATE_SHORT_REFS;
decoration_given = 1;
} else if (!prefixcmp(arg, "--decorate=")) {
const char *v = skip_prefix(arg, "--decorate=");
decoration_style = parse_decoration_style(arg, v);
if (decoration_style < 0)
die(_("invalid --decorate option: %s"), arg);
decoration_given = 1;
} else if (!strcmp(arg, "--no-decorate")) {
decoration_style = 0;
} else if (!strcmp(arg, "--source")) {
rev->show_source = 1;
} else if (!strcmp(arg, "-h")) {
usage(builtin_log_usage);
} else
die(_("unrecognized argument: %s"), arg);
}
/*
* defeat log.decorate configuration interacting with --pretty=raw
* from the command line.
*/
if (!decoration_given && rev->pretty_given
&& rev->commit_format == CMIT_FMT_RAW)
decoration_style = 0;
if (source)
rev->show_source = 1;
if (rev->pretty_given && rev->commit_format == CMIT_FMT_RAW) {
/*
* "log --pretty=raw" is special; ignore UI oriented
* configuration variables such as decoration.
*/
if (!decoration_given)
decoration_style = 0;
if (!rev->abbrev_commit_given)
rev->abbrev_commit = 0;
}
if (decoration_style) {
rev->show_decorations = 1;
@@ -309,6 +330,10 @@ static int git_log_config(const char *var, const char *value, void *cb)
return git_config_string(&fmt_pretty, var, value);
if (!strcmp(var, "format.subjectprefix"))
return git_config_string(&fmt_patch_subject_prefix, var, value);
if (!strcmp(var, "log.abbrevcommit")) {
default_abbrev_commit = git_config_bool(var, value);
return 0;
}
if (!strcmp(var, "log.date"))
return git_config_string(&default_date_mode, var, value);
if (!strcmp(var, "log.decorate")) {
@@ -351,9 +376,11 @@ int cmd_whatchanged(int argc, const char **argv, const char *prefix)
static void show_tagger(char *buf, int len, struct rev_info *rev)
{
struct strbuf out = STRBUF_INIT;
struct pretty_print_context pp = {0};
pp_user_info("Tagger", rev->commit_format, &out, buf, rev->date_mode,
get_log_output_encoding());
pp.fmt = rev->commit_format;
pp.date_mode = rev->date_mode;
pp_user_info(&pp, "Tagger", &out, buf, get_log_output_encoding());
printf("%s", out.buf);
strbuf_release(&out);
}
@@ -502,11 +529,11 @@ int cmd_log_reflog(int argc, const char **argv, const char *prefix)
init_revisions(&rev, prefix);
init_reflog_walk(&rev.reflog_info);
rev.abbrev_commit = 1;
rev.verbose_header = 1;
memset(&opt, 0, sizeof(opt));
opt.def = "HEAD";
cmd_log_init_defaults(&rev);
rev.abbrev_commit = 1;
rev.commit_format = CMIT_FMT_ONELINE;
rev.use_terminator = 1;
rev.always_show_header = 1;
@@ -737,10 +764,8 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
int quiet)
{
const char *committer;
const char *subject_start = NULL;
const char *body = "*** SUBJECT HERE ***\n\n*** BLURB HERE ***\n";
const char *msg;
const char *extra_headers = rev->extra_headers;
struct shortlog log;
struct strbuf sb = STRBUF_INIT;
int i;
@@ -748,6 +773,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
struct diff_options opts;
int need_8bit_cte = 0;
struct commit *commit = NULL;
struct pretty_print_context pp = {0};
if (rev->commit_format != CMIT_FMT_EMAIL)
die(_("Cover letter needs email format"));
@@ -779,7 +805,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
free(commit);
}
log_write_email_headers(rev, head, &subject_start, &extra_headers,
log_write_email_headers(rev, head, &pp.subject, &pp.after_subject,
&need_8bit_cte);
for (i = 0; !need_8bit_cte && i < nr; i++)
@@ -787,11 +813,11 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
need_8bit_cte = 1;
msg = body;
pp_user_info(NULL, CMIT_FMT_EMAIL, &sb, committer, DATE_RFC2822,
encoding);
pp_title_line(CMIT_FMT_EMAIL, &msg, &sb, subject_start, extra_headers,
encoding, need_8bit_cte);
pp_remainder(CMIT_FMT_EMAIL, &msg, &sb, 0);
pp.fmt = CMIT_FMT_EMAIL;
pp.date_mode = DATE_RFC2822;
pp_user_info(&pp, NULL, &sb, committer, encoding);
pp_title_line(&pp, &msg, &sb, encoding, need_8bit_cte);
pp_remainder(&pp, &msg, &sb, 0);
printf("%s\n", sb.buf);
strbuf_release(&sb);
@@ -1155,6 +1181,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
die (_("-n and -k are mutually exclusive."));
if (keep_subject && subject_prefix)
die (_("--subject-prefix and -k are mutually exclusive."));
rev.preserve_subject = keep_subject;
argc = setup_revisions(argc, argv, &rev, &s_r_opt);
if (argc > 1)
@@ -1385,8 +1412,7 @@ static void print_commit(char sign, struct commit *commit, int verbose,
find_unique_abbrev(commit->object.sha1, abbrev));
} else {
struct strbuf buf = STRBUF_INIT;
struct pretty_print_context ctx = {0};
pretty_print_commit(CMIT_FMT_ONELINE, commit, &buf, &ctx);
pp_commit_easy(CMIT_FMT_ONELINE, commit, &buf);
printf("%c %s %s\n", sign,
find_unique_abbrev(commit->object.sha1, abbrev),
buf.buf);

View File

@@ -5,7 +5,7 @@
static const char ls_remote_usage[] =
"git ls-remote [--heads] [--tags] [-u <exec> | --upload-pack <exec>]\n"
" [-q|--quiet] [<repository> [<refs>...]]";
" [-q|--quiet] [--exit-code] [<repository> [<refs>...]]";
/*
* Is there one among the list of patterns that match the tail part
@@ -35,6 +35,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
unsigned flags = 0;
int get_url = 0;
int quiet = 0;
int status = 0;
const char *uploadpack = NULL;
const char **pattern = NULL;
@@ -74,6 +75,11 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
get_url = 1;
continue;
}
if (!strcmp("--exit-code", arg)) {
/* return this code if no refs are reported */
status = 2;
continue;
}
usage(ls_remote_usage);
}
dest = arg;
@@ -121,6 +127,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
if (!tail_match(pattern, ref->name))
continue;
printf("%s %s\n", sha1_to_hex(ref->old_sha1), ref->name);
status = 0; /* we found something */
}
return 0;
return status;
}

View File

@@ -400,7 +400,7 @@ static int read_one_header_line(struct strbuf *line, FILE *in)
break;
if (strbuf_getline(&continuation, in, '\n'))
break;
continuation.buf[0] = '\n';
continuation.buf[0] = ' ';
strbuf_rtrim(&continuation);
strbuf_addbuf(line, &continuation);
}

View File

@@ -23,7 +23,8 @@ static int show_merge_base(struct commit **rev, int rev_nr, int show_all)
}
static const char * const merge_base_usage[] = {
"git merge-base [-a|--all] [--octopus] <commit> <commit>...",
"git merge-base [-a|--all] <commit> <commit>...",
"git merge-base [-a|--all] --octopus <commit>...",
"git merge-base --independent <commit>...",
NULL
};

View File

@@ -56,6 +56,7 @@ static size_t use_strategies_nr, use_strategies_alloc;
static const char **xopts;
static size_t xopts_nr, xopts_alloc;
static const char *branch;
static char *branch_mergeoptions;
static int option_renormalize;
static int verbosity;
static int allow_rerere_auto;
@@ -338,13 +339,14 @@ static void squash_message(void)
ctx.abbrev = rev.abbrev;
ctx.date_mode = rev.date_mode;
ctx.fmt = rev.commit_format;
strbuf_addstr(&out, "Squashed commit of the following:\n");
while ((commit = get_revision(&rev)) != NULL) {
strbuf_addch(&out, '\n');
strbuf_addf(&out, "commit %s\n",
sha1_to_hex(commit->object.sha1));
pretty_print_commit(rev.commit_format, commit, &out, &ctx);
pretty_print_commit(&ctx, commit, &out);
}
if (write(fd, out.buf, out.len) < 0)
die_errno(_("Writing SQUASH_MSG"));
@@ -503,26 +505,34 @@ cleanup:
strbuf_release(&bname);
}
static void parse_branch_merge_options(char *bmo)
{
const char **argv;
int argc;
if (!bmo)
return;
argc = split_cmdline(bmo, &argv);
if (argc < 0)
die(_("Bad branch.%s.mergeoptions string: %s"), branch,
split_cmdline_strerror(argc));
argv = xrealloc(argv, sizeof(*argv) * (argc + 2));
memmove(argv + 1, argv, sizeof(*argv) * (argc + 1));
argc++;
argv[0] = "branch.*.mergeoptions";
parse_options(argc, argv, NULL, builtin_merge_options,
builtin_merge_usage, 0);
free(argv);
}
static int git_merge_config(const char *k, const char *v, void *cb)
{
if (branch && !prefixcmp(k, "branch.") &&
!prefixcmp(k + 7, branch) &&
!strcmp(k + 7 + strlen(branch), ".mergeoptions")) {
const char **argv;
int argc;
char *buf;
buf = xstrdup(v);
argc = split_cmdline(buf, &argv);
if (argc < 0)
die(_("Bad branch.%s.mergeoptions string: %s"), branch,
split_cmdline_strerror(argc));
argv = xrealloc(argv, sizeof(*argv) * (argc + 2));
memmove(argv + 1, argv, sizeof(*argv) * (argc + 1));
argc++;
parse_options(argc, argv, NULL, builtin_merge_options,
builtin_merge_usage, 0);
free(buf);
free(branch_mergeoptions);
branch_mergeoptions = xstrdup(v);
return 0;
}
if (!strcmp(k, "merge.diffstat") || !strcmp(k, "merge.stat"))
@@ -541,6 +551,15 @@ static int git_merge_config(const char *k, const char *v, void *cb)
if (is_bool && shortlog_len)
shortlog_len = DEFAULT_MERGE_LOG_LEN;
return 0;
} else if (!strcmp(k, "merge.ff")) {
int boolval = git_config_maybe_bool(k, v);
if (0 <= boolval) {
allow_fast_forward = boolval;
} else if (v && !strcmp(v, "only")) {
allow_fast_forward = 1;
fast_forward_only = 1;
} /* do not barf on values from future versions of git */
return 0;
} else if (!strcmp(k, "merge.defaulttoupstream")) {
default_to_upstream = git_config_bool(k, v);
return 0;
@@ -590,6 +609,14 @@ static void write_tree_trivial(unsigned char *sha1)
die(_("git write-tree failed to write a tree"));
}
static const char *merge_argument(struct commit *commit)
{
if (commit)
return sha1_to_hex(commit->object.sha1);
else
return EMPTY_TREE_SHA1_HEX;
}
int try_merge_command(const char *strategy, size_t xopts_nr,
const char **xopts, struct commit_list *common,
const char *head_arg, struct commit_list *remotes)
@@ -610,11 +637,11 @@ int try_merge_command(const char *strategy, size_t xopts_nr,
args[i++] = s;
}
for (j = common; j; j = j->next)
args[i++] = xstrdup(sha1_to_hex(j->item->object.sha1));
args[i++] = xstrdup(merge_argument(j->item));
args[i++] = "--";
args[i++] = head_arg;
for (j = remotes; j; j = j->next)
args[i++] = xstrdup(sha1_to_hex(j->item->object.sha1));
args[i++] = xstrdup(merge_argument(j->item));
args[i] = NULL;
ret = run_command_v_opt(args, RUN_GIT_CMD);
strbuf_release(&buf);
@@ -1010,6 +1037,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
if (diff_use_color_default == -1)
diff_use_color_default = git_use_color_default;
if (branch_mergeoptions)
parse_branch_merge_options(branch_mergeoptions);
argc = parse_options(argc, argv, prefix, builtin_merge_options,
builtin_merge_usage, 0);

View File

@@ -23,8 +23,8 @@ static int verify_object(const unsigned char *sha1, const char *expected_type)
int ret = -1;
enum object_type type;
unsigned long size;
const unsigned char *repl;
void *buffer = read_sha1_file_repl(sha1, &type, &size, &repl);
void *buffer = read_sha1_file(sha1, &type, &size);
const unsigned char *repl = lookup_replace_object(sha1);
if (buffer) {
if (type == type_from_string(expected_type))

View File

@@ -29,7 +29,7 @@ static const char * const git_notes_usage[] = {
"git notes [--ref <notes_ref>] merge [-v | -q] [-s <strategy> ] <notes_ref>",
"git notes merge --commit [-v | -q]",
"git notes merge --abort [-v | -q]",
"git notes [--ref <notes_ref>] remove [<object>]",
"git notes [--ref <notes_ref>] remove [<object>...]",
"git notes [--ref <notes_ref>] prune [-n | -v]",
"git notes [--ref <notes_ref>] get-ref",
NULL
@@ -953,40 +953,60 @@ static int merge(int argc, const char **argv, const char *prefix)
return result < 0; /* return non-zero on conflicts */
}
#define IGNORE_MISSING 1
static int remove_one_note(struct notes_tree *t, const char *name, unsigned flag)
{
int status;
unsigned char sha1[20];
if (get_sha1(name, sha1))
return error(_("Failed to resolve '%s' as a valid ref."), name);
status = remove_note(t, sha1);
if (status)
fprintf(stderr, _("Object %s has no note\n"), name);
else
fprintf(stderr, _("Removing note for object %s\n"), name);
return (flag & IGNORE_MISSING) ? 0 : status;
}
static int remove_cmd(int argc, const char **argv, const char *prefix)
{
unsigned flag = 0;
int from_stdin = 0;
struct option options[] = {
OPT_BIT(0, "ignore-missing", &flag,
"attempt to remove non-existent note is not an error",
IGNORE_MISSING),
OPT_BOOLEAN(0, "stdin", &from_stdin,
"read object names from the standard input"),
OPT_END()
};
const char *object_ref;
struct notes_tree *t;
unsigned char object[20];
int retval;
int retval = 0;
argc = parse_options(argc, argv, prefix, options,
git_notes_remove_usage, 0);
if (1 < argc) {
error(_("too many parameters"));
usage_with_options(git_notes_remove_usage, options);
}
object_ref = argc ? argv[0] : "HEAD";
if (get_sha1(object_ref, object))
die(_("Failed to resolve '%s' as a valid ref."), object_ref);
t = init_notes_check("remove");
retval = remove_note(t, object);
if (retval)
fprintf(stderr, _("Object %s has no note\n"), sha1_to_hex(object));
else {
fprintf(stderr, _("Removing note for object %s\n"),
sha1_to_hex(object));
commit_notes(t, "Notes removed by 'git notes remove'");
if (!argc && !from_stdin) {
retval = remove_one_note(t, "HEAD", flag);
} else {
while (*argv) {
retval |= remove_one_note(t, *argv, flag);
argv++;
}
}
if (from_stdin) {
struct strbuf sb = STRBUF_INIT;
while (strbuf_getwholeline(&sb, stdin, '\n') != EOF) {
strbuf_rtrim(&sb);
retval |= remove_one_note(t, sb.buf, flag);
}
strbuf_release(&sb);
}
if (!retval)
commit_notes(t, "Notes removed by 'git notes remove'");
free_notes(t);
return retval;
}

View File

@@ -130,6 +130,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
PARSE_OPT_NONEG, exclude_per_directory_cb },
OPT_SET_INT('i', NULL, &opts.index_only,
"don't check the working tree after merging", 1),
OPT__DRY_RUN(&opts.dry_run, "don't update the index or the work tree"),
OPT_SET_INT(0, "no-sparse-checkout", &opts.skip_sparse_checkout,
"skip applying sparse checkout filter", 1),
OPT_SET_INT(0, "debug-unpack", &opts.debug_unpack,
@@ -219,7 +220,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
if (unpack_trees(nr_trees, t, &opts))
return 128;
if (opts.debug_unpack)
if (opts.debug_unpack || opts.dry_run)
return 0; /* do not write the index out */
/*

View File

@@ -10,6 +10,7 @@
#include "remote.h"
#include "transport.h"
#include "string-list.h"
#include "sha1-array.h"
static const char receive_pack_usage[] = "git receive-pack <git-dir>";
@@ -785,14 +786,23 @@ static int delete_only(struct command *commands)
return 1;
}
static void add_one_alternate_ref(const struct ref *ref, void *unused)
static void add_one_alternate_sha1(const unsigned char sha1[20], void *unused)
{
add_extra_ref(".have", ref->old_sha1, 0);
add_extra_ref(".have", sha1, 0);
}
static void collect_one_alternate_ref(const struct ref *ref, void *data)
{
struct sha1_array *sa = data;
sha1_array_append(sa, ref->old_sha1);
}
static void add_alternate_refs(void)
{
foreach_alt_odb(refs_from_alternate_cb, add_one_alternate_ref);
struct sha1_array sa = SHA1_ARRAY_INIT;
for_each_alternate_ref(collect_one_alternate_ref, &sa);
sha1_array_for_each_unique(&sa, add_one_alternate_sha1, NULL);
sha1_array_clear(&sa);
}
int cmd_receive_pack(int argc, const char **argv, const char *prefix)

View File

@@ -193,8 +193,8 @@ static int add(int argc, const char **argv)
if (mirror && master)
die("specifying a master branch makes no sense with --mirror");
if (mirror && track.nr)
die("specifying branches to track makes no sense with --mirror");
if (mirror && !(mirror & MIRROR_FETCH) && track.nr)
die("specifying branches to track makes sense only with fetch mirrors");
name = argv[0];
url = argv[1];

View File

@@ -12,74 +12,6 @@ static const char * const rerere_usage[] = {
NULL,
};
/* these values are days */
static int cutoff_noresolve = 15;
static int cutoff_resolve = 60;
static time_t rerere_created_at(const char *name)
{
struct stat st;
return stat(rerere_path(name, "preimage"), &st) ? (time_t) 0 : st.st_mtime;
}
static time_t rerere_last_used_at(const char *name)
{
struct stat st;
return stat(rerere_path(name, "postimage"), &st) ? (time_t) 0 : st.st_mtime;
}
static void unlink_rr_item(const char *name)
{
unlink(rerere_path(name, "thisimage"));
unlink(rerere_path(name, "preimage"));
unlink(rerere_path(name, "postimage"));
rmdir(git_path("rr-cache/%s", name));
}
static int git_rerere_gc_config(const char *var, const char *value, void *cb)
{
if (!strcmp(var, "gc.rerereresolved"))
cutoff_resolve = git_config_int(var, value);
else if (!strcmp(var, "gc.rerereunresolved"))
cutoff_noresolve = git_config_int(var, value);
else
return git_default_config(var, value, cb);
return 0;
}
static void garbage_collect(struct string_list *rr)
{
struct string_list to_remove = STRING_LIST_INIT_DUP;
DIR *dir;
struct dirent *e;
int i, cutoff;
time_t now = time(NULL), then;
git_config(git_rerere_gc_config, NULL);
dir = opendir(git_path("rr-cache"));
if (!dir)
die_errno("unable to open rr-cache directory");
while ((e = readdir(dir))) {
if (is_dot_or_dotdot(e->d_name))
continue;
then = rerere_last_used_at(e->d_name);
if (then) {
cutoff = cutoff_resolve;
} else {
then = rerere_created_at(e->d_name);
if (!then)
continue;
cutoff = cutoff_noresolve;
}
if (then < now - cutoff * 86400)
string_list_append(&to_remove, e->d_name);
}
for (i = 0; i < to_remove.nr; i++)
unlink_rr_item(to_remove.items[i].string);
string_list_clear(&to_remove, 0);
}
static int outf(void *dummy, mmbuffer_t *ptr, int nbuf)
{
int i;
@@ -148,14 +80,9 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
return 0;
if (!strcmp(argv[0], "clear")) {
for (i = 0; i < merge_rr.nr; i++) {
const char *name = (const char *)merge_rr.items[i].util;
if (!has_rerere_resolution(name))
unlink_rr_item(name);
}
unlink_or_warn(git_path("MERGE_RR"));
rerere_clear(&merge_rr);
} else if (!strcmp(argv[0], "gc"))
garbage_collect(&merge_rr);
rerere_gc(&merge_rr);
else if (!strcmp(argv[0], "status"))
for (i = 0; i < merge_rr.nr; i++)
printf("%s\n", merge_rr.items[i].string);

View File

@@ -55,7 +55,9 @@ static void show_commit(struct commit *commit, void *data)
graph_show_commit(revs->graph);
if (revs->count) {
if (commit->object.flags & SYMMETRIC_LEFT)
if (commit->object.flags & PATCHSAME)
revs->count_same++;
else if (commit->object.flags & SYMMETRIC_LEFT)
revs->count_left++;
else
revs->count_right++;
@@ -102,7 +104,8 @@ static void show_commit(struct commit *commit, void *data)
struct pretty_print_context ctx = {0};
ctx.abbrev = revs->abbrev;
ctx.date_mode = revs->date_mode;
pretty_print_commit(revs->commit_format, commit, &buf, &ctx);
ctx.fmt = revs->commit_format;
pretty_print_commit(&ctx, commit, &buf);
if (revs->graph) {
if (buf.len) {
if (revs->commit_format != CMIT_FMT_ONELINE)
@@ -406,8 +409,12 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
&info);
if (revs.count) {
if (revs.left_right)
if (revs.left_right && revs.cherry_mark)
printf("%d\t%d\t%d\n", revs.count_left, revs.count_right, revs.count_same);
else if (revs.left_right)
printf("%d\t%d\n", revs.count_left, revs.count_right);
else if (revs.cherry_mark)
printf("%d\t%d\n", revs.count_left + revs.count_right, revs.count_same);
else
printf("%d\n", revs.count_left + revs.count_right);
}

View File

@@ -44,6 +44,7 @@ static int is_rev_argument(const char *arg)
"--branches=",
"--branches",
"--header",
"--ignore-missing",
"--max-age=",
"--max-count=",
"--min-age=",

View File

@@ -408,8 +408,6 @@ static int do_pick_commit(void)
discard_cache();
if (!commit->parents) {
if (action == REVERT)
die (_("Cannot revert a root commit"));
parent = NULL;
}
else if (commit->parents->next) {
@@ -467,7 +465,7 @@ static int do_pick_commit(void)
strbuf_addstr(&msgbuf, "\"\n\nThis reverts commit ");
strbuf_addstr(&msgbuf, sha1_to_hex(commit->object.sha1));
if (commit->parents->next) {
if (commit->parents && commit->parents->next) {
strbuf_addstr(&msgbuf, ", reversing\nchanges made to ");
strbuf_addstr(&msgbuf, sha1_to_hex(parent->object.sha1));
}

View File

@@ -228,8 +228,11 @@ static void print_helper_status(struct ref *ref)
static int sideband_demux(int in, int out, void *data)
{
int *fd = data;
int ret = recv_sideband("send-pack", fd[0], out);
int *fd = data, ret;
#ifdef NO_PTHREADS
close(fd[1]);
#endif
ret = recv_sideband("send-pack", fd[0], out);
close(out);
return ret;
}
@@ -339,6 +342,10 @@ int send_pack(struct send_pack_args *args,
if (pack_objects(out, remote_refs, extra_have, args) < 0) {
for (ref = remote_refs; ref; ref = ref->next)
ref->status = REF_STATUS_NONE;
if (args->stateless_rpc)
close(out);
if (git_connection_is_socket(conn))
shutdown(fd[0], SHUT_WR);
if (use_sideband)
finish_async(&demux);
return -1;

View File

@@ -138,9 +138,8 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)
const char *author = NULL, *buffer;
struct strbuf buf = STRBUF_INIT;
struct strbuf ufbuf = STRBUF_INIT;
struct pretty_print_context ctx = {0};
pretty_print_commit(CMIT_FMT_RAW, commit, &buf, &ctx);
pp_commit_easy(CMIT_FMT_RAW, commit, &buf);
buffer = buf.buf;
while (*buffer && *buffer != '\n') {
const char *eol = strchr(buffer, '\n');
@@ -159,11 +158,12 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)
sha1_to_hex(commit->object.sha1));
if (log->user_format) {
struct pretty_print_context ctx = {0};
ctx.fmt = CMIT_FMT_USERFORMAT;
ctx.abbrev = log->abbrev;
ctx.subject = "";
ctx.after_subject = "";
ctx.date_mode = DATE_NORMAL;
pretty_print_commit(CMIT_FMT_USERFORMAT, commit, &ufbuf, &ctx);
pretty_print_commit(&ctx, commit, &ufbuf);
buffer = ufbuf.buf;
} else if (*buffer) {
buffer++;

View File

@@ -283,8 +283,7 @@ static void show_one_commit(struct commit *commit, int no_name)
struct commit_name *name = commit->util;
if (commit->object.parsed) {
struct pretty_print_context ctx = {0};
pretty_print_commit(CMIT_FMT_ONELINE, commit, &pretty, &ctx);
pp_commit_easy(CMIT_FMT_ONELINE, commit, &pretty);
pretty_str = pretty.buf;
}
if (!prefixcmp(pretty_str, "[PATCH] "))

View File

@@ -352,11 +352,22 @@ static int parse_msg_arg(const struct option *opt, const char *arg, int unset)
return 0;
}
static int strbuf_check_tag_ref(struct strbuf *sb, const char *name)
{
if (name[0] == '-')
return CHECK_REF_FORMAT_ERROR;
strbuf_reset(sb);
strbuf_addf(sb, "refs/tags/%s", name);
return check_ref_format(sb->buf);
}
int cmd_tag(int argc, const char **argv, const char *prefix)
{
struct strbuf buf = STRBUF_INIT;
struct strbuf ref = STRBUF_INIT;
unsigned char object[20], prev[20];
char ref[PATH_MAX];
const char *object_ref, *tag;
struct ref_lock *lock;
@@ -452,12 +463,10 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
if (get_sha1(object_ref, object))
die(_("Failed to resolve '%s' as a valid ref."), object_ref);
if (snprintf(ref, sizeof(ref), "refs/tags/%s", tag) > sizeof(ref) - 1)
die(_("tag name too long: %.*s..."), 50, tag);
if (check_ref_format(ref))
if (strbuf_check_tag_ref(&ref, tag))
die(_("'%s' is not a valid tag name."), tag);
if (!resolve_ref(ref, prev, 1, NULL))
if (!resolve_ref(ref.buf, prev, 1, NULL))
hashclr(prev);
else if (!force)
die(_("tag '%s' already exists"), tag);
@@ -466,14 +475,15 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
create_tag(object, tag, &buf, msg.given || msgfile,
sign, prev, object);
lock = lock_any_ref_for_update(ref, prev, 0);
lock = lock_any_ref_for_update(ref.buf, prev, 0);
if (!lock)
die(_("%s: cannot lock the ref"), ref);
die(_("%s: cannot lock the ref"), ref.buf);
if (write_ref_sha1(lock, object, NULL) < 0)
die(_("%s: cannot update the ref"), ref);
die(_("%s: cannot update the ref"), ref.buf);
if (force && hashcmp(prev, object))
printf(_("Updated tag '%s' (was %s)\n"), tag, find_unique_abbrev(prev, DEFAULT_ABBREV));
strbuf_release(&buf);
strbuf_release(&ref);
return 0;
}

View File

@@ -99,7 +99,8 @@ static int add_one_path(struct cache_entry *old, const char *path, int len, stru
fill_stat_cache_info(ce, st);
ce->ce_mode = ce_mode_from_stat(old, st->st_mode);
if (index_path(ce->sha1, path, st, !info_only))
if (index_path(ce->sha1, path, st,
info_only ? 0 : HASH_WRITE_OBJECT))
return -1;
option = allow_add ? ADD_CACHE_OK_TO_ADD : 0;
option |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0;

View File

@@ -33,9 +33,9 @@ static void show_pack_info(struct packed_git *p, unsigned int flags)
if (!sha1)
die("internal error pack-check nth-packed-object");
offset = nth_packed_object_offset(p, i);
type = packed_object_info_detail(p, offset, &size, &store_size,
type = typename(packed_object_info_detail(p, offset, &size, &store_size,
&delta_chain_length,
base_sha1);
base_sha1));
if (!stat_only)
printf("%s ", sha1_to_hex(sha1));
if (!delta_chain_length) {

106
cache.h
View File

@@ -518,8 +518,11 @@ struct pathspec {
extern int init_pathspec(struct pathspec *, const char **);
extern void free_pathspec(struct pathspec *);
extern int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec);
extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path, int format_check);
extern int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object);
#define HASH_WRITE_OBJECT 1
#define HASH_FORMAT_CHECK 2
extern int index_fd(unsigned char *sha1, int fd, struct stat *st, enum object_type type, const char *path, unsigned flags);
extern int index_path(unsigned char *sha1, const char *path, struct stat *st, unsigned flags);
extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
#define REFRESH_REALLY 0x0001 /* ignore_valid */
@@ -613,7 +616,7 @@ enum eol {
#endif
};
extern enum eol eol;
extern enum eol core_eol;
enum branch_track {
BRANCH_TRACK_UNSPECIFIED = -1,
@@ -683,14 +686,24 @@ extern char *sha1_pack_name(const unsigned char *sha1);
extern char *sha1_pack_index_name(const unsigned char *sha1);
extern const char *find_unique_abbrev(const unsigned char *sha1, int);
extern const unsigned char null_sha1[20];
static inline int is_null_sha1(const unsigned char *sha1)
{
return !memcmp(sha1, null_sha1, 20);
}
static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2)
{
return memcmp(sha1, sha2, 20);
int i;
for (i = 0; i < 20; i++, sha1++, sha2++) {
if (*sha1 != *sha2)
return *sha1 - *sha2;
}
return 0;
}
static inline int is_null_sha1(const unsigned char *sha1)
{
return !hashcmp(sha1, null_sha1);
}
static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src)
{
memcpy(sha_dst, sha_src, 20);
@@ -741,7 +754,7 @@ extern char *expand_user_path(const char *path);
char *enter_repo(char *path, int strict);
static inline int is_absolute_path(const char *path)
{
return path[0] == '/' || has_dos_drive_prefix(path);
return is_dir_sep(path[0]) || has_dos_drive_prefix(path);
}
int is_directory(const char *);
const char *real_path(const char *path);
@@ -752,17 +765,30 @@ int longest_ancestor_length(const char *path, const char *prefix_list);
char *strip_path_suffix(const char *path, const char *suffix);
int daemon_avoid_alias(const char *path);
/* Read and unpack a sha1 file into memory, write memory to a sha1 file */
extern int sha1_object_info(const unsigned char *, unsigned long *);
extern void *read_sha1_file_repl(const unsigned char *sha1, enum object_type *type, unsigned long *size, const unsigned char **replacement);
/* object replacement */
#define READ_SHA1_FILE_REPLACE 1
extern void *read_sha1_file_extended(const unsigned char *sha1, enum object_type *type, unsigned long *size, unsigned flag);
static inline void *read_sha1_file(const unsigned char *sha1, enum object_type *type, unsigned long *size)
{
return read_sha1_file_repl(sha1, type, size, NULL);
return read_sha1_file_extended(sha1, type, size, READ_SHA1_FILE_REPLACE);
}
extern const unsigned char *do_lookup_replace_object(const unsigned char *sha1);
static inline const unsigned char *lookup_replace_object(const unsigned char *sha1)
{
if (!read_replace_refs)
return sha1;
return do_lookup_replace_object(sha1);
}
/* Read and unpack a sha1 file into memory, write memory to a sha1 file */
extern int sha1_object_info(const unsigned char *, unsigned long *);
extern int hash_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1);
extern int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *return_sha1);
extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned char *);
extern int force_object_loose(const unsigned char *sha1, time_t mtime);
extern void *map_sha1_file(const unsigned char *sha1, unsigned long *size);
extern int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz);
extern int parse_sha1_header(const char *hdr, unsigned long *sizep);
/* global flag to enable extra checks when accessing packed objects */
extern int do_check_packed_object_crc;
@@ -796,15 +822,15 @@ struct object_context {
};
extern int get_sha1(const char *str, unsigned char *sha1);
extern int get_sha1_with_mode_1(const char *str, unsigned char *sha1, unsigned *mode, int gently, const char *prefix);
extern int get_sha1_with_mode_1(const char *str, unsigned char *sha1, unsigned *mode, int only_to_die, const char *prefix);
static inline int get_sha1_with_mode(const char *str, unsigned char *sha1, unsigned *mode)
{
return get_sha1_with_mode_1(str, sha1, mode, 1, NULL);
return get_sha1_with_mode_1(str, sha1, mode, 0, NULL);
}
extern int get_sha1_with_context_1(const char *name, unsigned char *sha1, struct object_context *orc, int gently, const char *prefix);
extern int get_sha1_with_context_1(const char *name, unsigned char *sha1, struct object_context *orc, int only_to_die, const char *prefix);
static inline int get_sha1_with_context(const char *str, unsigned char *sha1, struct object_context *orc)
{
return get_sha1_with_context_1(str, sha1, orc, 1, NULL);
return get_sha1_with_context_1(str, sha1, orc, 0, NULL);
}
extern int get_sha1_hex(const char *hex, unsigned char *sha1);
extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */
@@ -971,6 +997,7 @@ extern struct ref *find_ref_by_name(const struct ref *list, const char *name);
extern char *git_getpass(const char *prompt);
extern struct child_process *git_connect(int fd[2], const char *url, const char *prog, int flags);
extern int finish_connect(struct child_process *conn);
extern int git_connection_is_socket(struct child_process *conn);
extern int path_match(const char *path, int nr, char **match);
struct extra_have_objects {
int nr, alloc;
@@ -1003,17 +1030,55 @@ extern off_t find_pack_entry_one(const unsigned char *, struct packed_git *);
extern void *unpack_entry(struct packed_git *, off_t, enum object_type *, unsigned long *);
extern unsigned long unpack_object_header_buffer(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep);
extern unsigned long get_size_from_delta(struct packed_git *, struct pack_window **, off_t);
extern const char *packed_object_info_detail(struct packed_git *, off_t, unsigned long *, unsigned long *, unsigned int *, unsigned char *);
extern int packed_object_info_detail(struct packed_git *, off_t, unsigned long *, unsigned long *, unsigned int *, unsigned char *);
extern int unpack_object_header(struct packed_git *, struct pack_window **, off_t *, unsigned long *);
struct object_info {
/* Request */
unsigned long *sizep;
/* Response */
enum {
OI_CACHED,
OI_LOOSE,
OI_PACKED,
OI_DBCACHED
} whence;
union {
/*
* struct {
* ... Nothing to expose in this case
* } cached;
* struct {
* ... Nothing to expose in this case
* } loose;
*/
struct {
struct packed_git *pack;
off_t offset;
unsigned int is_delta;
} packed;
} u;
};
extern int sha1_object_info_extended(const unsigned char *, struct object_info *);
/* Dumb servers support */
extern int update_server_info(int);
/* git_config_parse_key() returns these negated: */
#define CONFIG_INVALID_KEY 1
#define CONFIG_NO_SECTION_OR_NAME 2
/* git_config_set(), git_config_set_multivar() return the above or these: */
#define CONFIG_NO_LOCK -1
#define CONFIG_INVALID_FILE 3
#define CONFIG_NO_WRITE 4
#define CONFIG_NOTHING_SET 5
#define CONFIG_INVALID_PATTERN 6
typedef int (*config_fn_t)(const char *, const char *, void *);
extern int git_default_config(const char *, const char *, void *);
extern int git_config_from_file(config_fn_t fn, const char *, void *);
extern void git_config_push_parameter(const char *text);
extern int git_config_parse_parameter(const char *text);
extern int git_config_parse_environment(void);
extern int git_config_from_parameters(config_fn_t fn, void *data);
extern int git_config(config_fn_t fn, void *);
extern int git_config_early(config_fn_t fn, void *, const char *repo_config);
@@ -1109,6 +1174,7 @@ extern int convert_to_git(const char *path, const char *src, size_t len,
struct strbuf *dst, enum safe_crlf checksafe);
extern int convert_to_working_tree(const char *path, const char *src, size_t len, struct strbuf *dst);
extern int renormalize_buffer(const char *path, const char *src, size_t len, struct strbuf *dst);
extern int can_bypass_conversion(const char *path);
/* add */
/*

View File

@@ -7,6 +7,7 @@
#include "xdiff-interface.h"
#include "log-tree.h"
#include "refs.h"
#include "userdiff.h"
static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, int n, int num_parent)
{
@@ -92,7 +93,9 @@ struct sline {
unsigned long *p_lno;
};
static char *grab_blob(const unsigned char *sha1, unsigned int mode, unsigned long *size)
static char *grab_blob(const unsigned char *sha1, unsigned int mode,
unsigned long *size, struct userdiff_driver *textconv,
const char *path)
{
char *blob;
enum object_type type;
@@ -105,6 +108,11 @@ static char *grab_blob(const unsigned char *sha1, unsigned int mode, unsigned lo
/* deleted blob */
*size = 0;
return xcalloc(1, 1);
} else if (textconv) {
struct diff_filespec *df = alloc_filespec(path);
fill_filespec(df, sha1, mode);
*size = fill_textconv(textconv, df, &blob);
free_filespec(df);
} else {
blob = read_sha1_file(sha1, &type, size);
if (type != OBJ_BLOB)
@@ -204,7 +212,9 @@ static void consume_line(void *state_, char *line, unsigned long len)
static void combine_diff(const unsigned char *parent, unsigned int mode,
mmfile_t *result_file,
struct sline *sline, unsigned int cnt, int n,
int num_parent, int result_deleted)
int num_parent, int result_deleted,
struct userdiff_driver *textconv,
const char *path)
{
unsigned int p_lno, lno;
unsigned long nmask = (1UL << n);
@@ -217,7 +227,7 @@ static void combine_diff(const unsigned char *parent, unsigned int mode,
if (result_deleted)
return; /* result deleted */
parent_file.ptr = grab_blob(parent, mode, &sz);
parent_file.ptr = grab_blob(parent, mode, &sz, textconv, path);
parent_file.size = sz;
memset(&xpp, 0, sizeof(xpp));
xpp.flags = 0;
@@ -681,6 +691,82 @@ static void dump_quoted_path(const char *head,
puts(buf.buf);
}
static void show_combined_header(struct combine_diff_path *elem,
int num_parent,
int dense,
struct rev_info *rev,
int mode_differs,
int show_file_header)
{
struct diff_options *opt = &rev->diffopt;
int abbrev = DIFF_OPT_TST(opt, FULL_INDEX) ? 40 : DEFAULT_ABBREV;
const char *a_prefix = opt->a_prefix ? opt->a_prefix : "a/";
const char *b_prefix = opt->b_prefix ? opt->b_prefix : "b/";
int use_color = DIFF_OPT_TST(opt, COLOR_DIFF);
const char *c_meta = diff_get_color(use_color, DIFF_METAINFO);
const char *c_reset = diff_get_color(use_color, DIFF_RESET);
const char *abb;
int added = 0;
int deleted = 0;
int i;
if (rev->loginfo && !rev->no_commit_id)
show_log(rev);
dump_quoted_path(dense ? "diff --cc " : "diff --combined ",
"", elem->path, c_meta, c_reset);
printf("%sindex ", c_meta);
for (i = 0; i < num_parent; i++) {
abb = find_unique_abbrev(elem->parent[i].sha1,
abbrev);
printf("%s%s", i ? "," : "", abb);
}
abb = find_unique_abbrev(elem->sha1, abbrev);
printf("..%s%s\n", abb, c_reset);
if (mode_differs) {
deleted = !elem->mode;
/* We say it was added if nobody had it */
added = !deleted;
for (i = 0; added && i < num_parent; i++)
if (elem->parent[i].status !=
DIFF_STATUS_ADDED)
added = 0;
if (added)
printf("%snew file mode %06o",
c_meta, elem->mode);
else {
if (deleted)
printf("%sdeleted file ", c_meta);
printf("mode ");
for (i = 0; i < num_parent; i++) {
printf("%s%06o", i ? "," : "",
elem->parent[i].mode);
}
if (elem->mode)
printf("..%06o", elem->mode);
}
printf("%s\n", c_reset);
}
if (!show_file_header)
return;
if (added)
dump_quoted_path("--- ", "", "/dev/null",
c_meta, c_reset);
else
dump_quoted_path("--- ", a_prefix, elem->path,
c_meta, c_reset);
if (deleted)
dump_quoted_path("+++ ", "", "/dev/null",
c_meta, c_reset);
else
dump_quoted_path("+++ ", b_prefix, elem->path,
c_meta, c_reset);
}
static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
int dense, struct rev_info *rev)
{
@@ -692,17 +778,22 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
int mode_differs = 0;
int i, show_hunks;
int working_tree_file = is_null_sha1(elem->sha1);
int abbrev = DIFF_OPT_TST(opt, FULL_INDEX) ? 40 : DEFAULT_ABBREV;
const char *a_prefix, *b_prefix;
mmfile_t result_file;
struct userdiff_driver *userdiff;
struct userdiff_driver *textconv = NULL;
int is_binary;
context = opt->context;
a_prefix = opt->a_prefix ? opt->a_prefix : "a/";
b_prefix = opt->b_prefix ? opt->b_prefix : "b/";
userdiff = userdiff_find_by_path(elem->path);
if (!userdiff)
userdiff = userdiff_find_by_name("default");
if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV))
textconv = userdiff_get_textconv(userdiff);
/* Read the result of merge first */
if (!working_tree_file)
result = grab_blob(elem->sha1, elem->mode, &result_size);
result = grab_blob(elem->sha1, elem->mode, &result_size,
textconv, elem->path);
else {
/* Used by diff-tree to read from the working tree */
struct stat st;
@@ -725,9 +816,16 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
} else if (S_ISDIR(st.st_mode)) {
unsigned char sha1[20];
if (resolve_gitlink_ref(elem->path, "HEAD", sha1) < 0)
result = grab_blob(elem->sha1, elem->mode, &result_size);
result = grab_blob(elem->sha1, elem->mode,
&result_size, NULL, NULL);
else
result = grab_blob(sha1, elem->mode, &result_size);
result = grab_blob(sha1, elem->mode,
&result_size, NULL, NULL);
} else if (textconv) {
struct diff_filespec *df = alloc_filespec(elem->path);
fill_filespec(df, null_sha1, st.st_mode);
result_size = fill_textconv(textconv, df, &result);
free_filespec(df);
} else if (0 <= (fd = open(elem->path, O_RDONLY))) {
size_t len = xsize_t(st.st_size);
ssize_t done;
@@ -777,6 +875,38 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
close(fd);
}
for (i = 0; i < num_parent; i++) {
if (elem->parent[i].mode != elem->mode) {
mode_differs = 1;
break;
}
}
if (textconv)
is_binary = 0;
else if (userdiff->binary != -1)
is_binary = userdiff->binary;
else {
is_binary = buffer_is_binary(result, result_size);
for (i = 0; !is_binary && i < num_parent; i++) {
char *buf;
unsigned long size;
buf = grab_blob(elem->parent[i].sha1,
elem->parent[i].mode,
&size, NULL, NULL);
if (buffer_is_binary(buf, size))
is_binary = 1;
free(buf);
}
}
if (is_binary) {
show_combined_header(elem, num_parent, dense, rev,
mode_differs, 0);
printf("Binary files differ\n");
free(result);
return;
}
for (cnt = 0, cp = result; cp < result + result_size; cp++) {
if (*cp == '\n')
cnt++;
@@ -824,71 +954,15 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
combine_diff(elem->parent[i].sha1,
elem->parent[i].mode,
&result_file, sline,
cnt, i, num_parent, result_deleted);
if (elem->parent[i].mode != elem->mode)
mode_differs = 1;
cnt, i, num_parent, result_deleted,
textconv, elem->path);
}
show_hunks = make_hunks(sline, cnt, num_parent, dense);
if (show_hunks || mode_differs || working_tree_file) {
const char *abb;
int use_color = DIFF_OPT_TST(opt, COLOR_DIFF);
const char *c_meta = diff_get_color(use_color, DIFF_METAINFO);
const char *c_reset = diff_get_color(use_color, DIFF_RESET);
int added = 0;
int deleted = 0;
if (rev->loginfo && !rev->no_commit_id)
show_log(rev);
dump_quoted_path(dense ? "diff --cc " : "diff --combined ",
"", elem->path, c_meta, c_reset);
printf("%sindex ", c_meta);
for (i = 0; i < num_parent; i++) {
abb = find_unique_abbrev(elem->parent[i].sha1,
abbrev);
printf("%s%s", i ? "," : "", abb);
}
abb = find_unique_abbrev(elem->sha1, abbrev);
printf("..%s%s\n", abb, c_reset);
if (mode_differs) {
deleted = !elem->mode;
/* We say it was added if nobody had it */
added = !deleted;
for (i = 0; added && i < num_parent; i++)
if (elem->parent[i].status !=
DIFF_STATUS_ADDED)
added = 0;
if (added)
printf("%snew file mode %06o",
c_meta, elem->mode);
else {
if (deleted)
printf("%sdeleted file ", c_meta);
printf("mode ");
for (i = 0; i < num_parent; i++) {
printf("%s%06o", i ? "," : "",
elem->parent[i].mode);
}
if (elem->mode)
printf("..%06o", elem->mode);
}
printf("%s\n", c_reset);
}
if (added)
dump_quoted_path("--- ", "", "/dev/null",
c_meta, c_reset);
else
dump_quoted_path("--- ", a_prefix, elem->path,
c_meta, c_reset);
if (deleted)
dump_quoted_path("+++ ", "", "/dev/null",
c_meta, c_reset);
else
dump_quoted_path("+++ ", b_prefix, elem->path,
c_meta, c_reset);
show_combined_header(elem, num_parent, dense, rev,
mode_differs, 1);
dump_sline(sline, cnt, num_parent,
DIFF_OPT_TST(opt, COLOR_DIFF), result_deleted);
}

View File

@@ -69,9 +69,11 @@ enum cmit_fmt {
};
struct pretty_print_context {
enum cmit_fmt fmt;
int abbrev;
const char *subject;
const char *after_subject;
int preserve_subject;
enum date_mode date_mode;
int need_8bit_cte;
int show_notes;
@@ -96,20 +98,20 @@ extern void userformat_find_requirements(const char *fmt, struct userformat_want
extern void format_commit_message(const struct commit *commit,
const char *format, struct strbuf *sb,
const struct pretty_print_context *context);
extern void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
struct strbuf *sb,
const struct pretty_print_context *context);
void pp_user_info(const char *what, enum cmit_fmt fmt, struct strbuf *sb,
const char *line, enum date_mode dmode,
const char *encoding);
void pp_title_line(enum cmit_fmt fmt,
extern void pretty_print_commit(const struct pretty_print_context *pp,
const struct commit *commit,
struct strbuf *sb);
extern void pp_commit_easy(enum cmit_fmt fmt, const struct commit *commit,
struct strbuf *sb);
void pp_user_info(const struct pretty_print_context *pp,
const char *what, struct strbuf *sb,
const char *line, const char *encoding);
void pp_title_line(const struct pretty_print_context *pp,
const char **msg_p,
struct strbuf *sb,
const char *subject,
const char *after_subject,
const char *encoding,
int need_8bit_cte);
void pp_remainder(enum cmit_fmt fmt,
void pp_remainder(const struct pretty_print_context *pp,
const char **msg_p,
struct strbuf *sb,
int indent);
@@ -145,8 +147,6 @@ struct commit_graft *read_graft_line(char *buf, int len);
int register_commit_graft(struct commit_graft *, int);
struct commit_graft *lookup_commit_graft(const unsigned char *sha1);
const unsigned char *lookup_replace_object(const unsigned char *sha1);
extern struct commit_list *get_merge_bases(struct commit *rev1, struct commit *rev2, int cleanup);
extern struct commit_list *get_merge_bases_many(struct commit *one, int n, struct commit **twos, int cleanup);
extern struct commit_list *get_octopus_merge_bases(struct commit_list *in);
@@ -161,7 +161,7 @@ extern struct commit_list *get_shallow_commits(struct object_array *heads,
int is_descendant_of(struct commit *, struct commit_list *);
int in_merge_bases(struct commit *, struct commit **, int);
extern int interactive_add(int argc, const char **argv, const char *prefix);
extern int interactive_add(int argc, const char **argv, const char *prefix, int patch);
extern int run_add_interactive(const char *revision, const char *patch_mode,
const char **pathspec);

View File

@@ -127,6 +127,10 @@ extern char *getenv ();
extern int errno;
# endif
# ifndef NULL
# define NULL 0
# endif
/* This function doesn't exist on most systems. */
# if !defined HAVE___STRCHRNUL && !defined _LIBC

View File

@@ -475,7 +475,7 @@ static int do_lstat(int follow, const char *file_name, struct stat *buf)
static int do_stat_internal(int follow, const char *file_name, struct stat *buf)
{
int namelen;
static char alt_name[PATH_MAX];
char alt_name[PATH_MAX];
if (!do_lstat(follow, file_name, buf))
return 0;
@@ -1452,6 +1452,13 @@ int mingw_setsockopt(int sockfd, int lvl, int optname, void *optval, int optlen)
return setsockopt(s, lvl, optname, (const char*)optval, optlen);
}
#undef shutdown
int mingw_shutdown(int sockfd, int how)
{
SOCKET s = (SOCKET)_get_osfhandle(sockfd);
return shutdown(s, how);
}
#undef listen
int mingw_listen(int sockfd, int backlog)
{
@@ -1845,3 +1852,24 @@ int mingw_offset_1st_component(const char *path)
return offset + is_dir_sep(path[offset]);
}
/*
* Disable MSVCRT command line wildcard expansion (__getmainargs called from
* mingw startup code, see init.c in mingw runtime).
*/
int _CRT_glob = 0;
void mingw_startup()
{
/* copy executable name to argv[0] */
__argv[0] = xstrdup(_pgmptr);
/* initialize critical section for waitpid pinfo_t list */
InitializeCriticalSection(&pinfo_cs);
/* set up default file mode and file modes for stdin/out/err */
_fmode = _O_BINARY;
_setmode(_fileno(stdin), _O_BINARY);
_setmode(_fileno(stdout), _O_BINARY);
_setmode(_fileno(stderr), _O_BINARY);
}

View File

@@ -14,12 +14,6 @@ typedef int socklen_t;
#define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK)
#define S_ISSOCK(x) 0
#ifndef _STAT_H_
#define S_IRUSR 0
#define S_IWUSR 0
#define S_IXUSR 0
#define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
#endif
#define S_IRGRP 0
#define S_IWGRP 0
#define S_IXGRP 0
@@ -220,6 +214,9 @@ int mingw_bind(int sockfd, struct sockaddr *sa, size_t sz);
int mingw_setsockopt(int sockfd, int lvl, int optname, void *optval, int optlen);
#define setsockopt mingw_setsockopt
int mingw_shutdown(int sockfd, int how);
#define shutdown mingw_shutdown
int mingw_listen(int sockfd, int backlog);
#define listen mingw_listen
@@ -302,6 +299,15 @@ int winansi_vfprintf(FILE *stream, const char *format, va_list list);
#define has_dos_drive_prefix(path) (isalpha(*(path)) && (path)[1] == ':')
#define is_dir_sep(c) ((c) == '/' || (c) == '\\')
static inline char *mingw_find_last_dir_sep(const char *path)
{
char *ret = NULL;
for (; *path; ++path)
if (is_dir_sep(*path))
ret = (char *)path;
return ret;
}
#define find_last_dir_sep mingw_find_last_dir_sep
int mingw_offset_1st_component(const char *path);
#define offset_1st_component mingw_offset_1st_component
#define PATH_SEP ';'
@@ -321,22 +327,16 @@ char **make_augmented_environ(const char *const *vars);
void free_environ(char **env);
/*
* A replacement of main() that ensures that argv[0] has a path
* and that default fmode and std(in|out|err) are in binary mode
* A replacement of main() that adds win32 specific initialization.
*/
void mingw_startup();
#define main(c,v) dummy_decl_mingw_main(); \
static int mingw_main(); \
int main(int argc, const char **argv) \
{ \
extern CRITICAL_SECTION pinfo_cs; \
_fmode = _O_BINARY; \
_setmode(_fileno(stdin), _O_BINARY); \
_setmode(_fileno(stdout), _O_BINARY); \
_setmode(_fileno(stderr), _O_BINARY); \
argv[0] = xstrdup(_pgmptr); \
InitializeCriticalSection(&pinfo_cs); \
return mingw_main(argc, argv); \
mingw_startup(); \
return mingw_main(__argc, __argv); \
} \
static int mingw_main(c,v)

View File

@@ -1,96 +1,91 @@
#include "../git-compat-util.h"
#include "dirent.h"
#include "../../git-compat-util.h"
struct DIR {
struct dirent dd_dir; /* includes d_type */
HANDLE dd_handle; /* FindFirstFile handle */
int dd_stat; /* 0-based index */
char dd_name[1]; /* extend struct */
};
static inline void finddata2dirent(struct dirent *ent, WIN32_FIND_DATAA *fdata)
{
/* copy file name from WIN32_FIND_DATA to dirent */
memcpy(ent->d_name, fdata->cFileName, sizeof(ent->d_name));
/* Set file type, based on WIN32_FIND_DATA */
if (fdata->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
ent->d_type = DT_DIR;
else
ent->d_type = DT_REG;
}
DIR *opendir(const char *name)
{
DWORD attrs = GetFileAttributesA(name);
char pattern[MAX_PATH];
WIN32_FIND_DATAA fdata;
HANDLE h;
int len;
DIR *p;
DIR *dir;
/* check for valid path */
if (attrs == INVALID_FILE_ATTRIBUTES) {
errno = ENOENT;
/* check that name is not NULL */
if (!name) {
errno = EINVAL;
return NULL;
}
/* check if it's a directory */
if (!(attrs & FILE_ATTRIBUTE_DIRECTORY)) {
errno = ENOTDIR;
return NULL;
}
/* check that the pattern won't be too long for FindFirstFileA */
len = strlen(name);
if (is_dir_sep(name[len - 1]))
len--;
if (len + 2 >= MAX_PATH) {
errno = ENAMETOOLONG;
return NULL;
}
/* copy name to temp buffer */
memcpy(pattern, name, len + 1);
p = malloc(sizeof(DIR) + len + 2);
if (!p)
/* append optional '/' and wildcard '*' */
if (len && !is_dir_sep(pattern[len - 1]))
pattern[len++] = '/';
pattern[len++] = '*';
pattern[len] = 0;
/* open find handle */
h = FindFirstFileA(pattern, &fdata);
if (h == INVALID_HANDLE_VALUE) {
DWORD err = GetLastError();
errno = (err == ERROR_DIRECTORY) ? ENOTDIR : err_win_to_posix(err);
return NULL;
}
memset(p, 0, sizeof(DIR) + len + 2);
strcpy(p->dd_name, name);
p->dd_name[len] = '/';
p->dd_name[len+1] = '*';
p->dd_handle = INVALID_HANDLE_VALUE;
return p;
/* initialize DIR structure and copy first dir entry */
dir = xmalloc(sizeof(DIR));
dir->dd_handle = h;
dir->dd_stat = 0;
finddata2dirent(&dir->dd_dir, &fdata);
return dir;
}
struct dirent *readdir(DIR *dir)
{
WIN32_FIND_DATAA buf;
HANDLE handle;
if (!dir || !dir->dd_handle) {
if (!dir) {
errno = EBADF; /* No set_errno for mingw */
return NULL;
}
if (dir->dd_handle == INVALID_HANDLE_VALUE && dir->dd_stat == 0) {
DWORD lasterr;
handle = FindFirstFileA(dir->dd_name, &buf);
lasterr = GetLastError();
dir->dd_handle = handle;
if (handle == INVALID_HANDLE_VALUE && (lasterr != ERROR_NO_MORE_FILES)) {
errno = err_win_to_posix(lasterr);
/* if first entry, dirent has already been set up by opendir */
if (dir->dd_stat) {
/* get next entry and convert from WIN32_FIND_DATA to dirent */
WIN32_FIND_DATAA fdata;
if (FindNextFileA(dir->dd_handle, &fdata)) {
finddata2dirent(&dir->dd_dir, &fdata);
} else {
DWORD lasterr = GetLastError();
/* POSIX says you shouldn't set errno when readdir can't
find any more files; so, if another error we leave it set. */
if (lasterr != ERROR_NO_MORE_FILES)
errno = err_win_to_posix(lasterr);
return NULL;
}
} else if (dir->dd_handle == INVALID_HANDLE_VALUE) {
return NULL;
} else if (!FindNextFileA(dir->dd_handle, &buf)) {
DWORD lasterr = GetLastError();
FindClose(dir->dd_handle);
dir->dd_handle = INVALID_HANDLE_VALUE;
/* POSIX says you shouldn't set errno when readdir can't
find any more files; so, if another error we leave it set. */
if (lasterr != ERROR_NO_MORE_FILES)
errno = err_win_to_posix(lasterr);
return NULL;
}
/* We get here if `buf' contains valid data. */
strcpy(dir->dd_dir.d_name, buf.cFileName);
++dir->dd_stat;
/* Set file type, based on WIN32_FIND_DATA */
dir->dd_dir.d_type = 0;
if (buf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
dir->dd_dir.d_type |= DT_DIR;
else
dir->dd_dir.d_type |= DT_REG;
return &dir->dd_dir;
}
@@ -101,8 +96,7 @@ int closedir(DIR *dir)
return -1;
}
if (dir->dd_handle != INVALID_HANDLE_VALUE)
FindClose(dir->dd_handle);
FindClose(dir->dd_handle);
free(dir);
return 0;
}

View File

@@ -9,12 +9,8 @@ typedef struct DIR DIR;
#define DT_LNK 3
struct dirent {
long d_ino; /* Always zero. */
char d_name[FILENAME_MAX]; /* File name. */
union {
unsigned short d_reclen; /* Always zero. */
unsigned char d_type; /* Reimplementation adds this */
};
unsigned char d_type; /* file type to prevent lstat after readdir */
char d_name[MAX_PATH]; /* file name */
};
DIR *opendir(const char *dirname);

View File

@@ -20,14 +20,6 @@ static int zlib_compression_seen;
const char *config_exclusive_filename = NULL;
struct config_item {
struct config_item *next;
char *name;
char *value;
};
static struct config_item *config_parameters;
static struct config_item **config_parameters_tail = &config_parameters;
static void lowercase(char *p)
{
for (; *p; p++)
@@ -47,9 +39,9 @@ void git_config_push_parameter(const char *text)
strbuf_release(&env);
}
int git_config_parse_parameter(const char *text)
static int git_config_parse_parameter(const char *text,
config_fn_t fn, void *data)
{
struct config_item *ct;
struct strbuf tmp = STRBUF_INIT;
struct strbuf **pair;
strbuf_addstr(&tmp, text);
@@ -58,23 +50,20 @@ int git_config_parse_parameter(const char *text)
strbuf_setlen(pair[0], pair[0]->len - 1);
strbuf_trim(pair[0]);
if (!pair[0]->len) {
strbuf_list_free(pair);
return error("bogus config parameter: %s", text);
}
lowercase(pair[0]->buf);
if (fn(pair[0]->buf, pair[1] ? pair[1]->buf : NULL, data) < 0) {
strbuf_list_free(pair);
return -1;
}
ct = xcalloc(1, sizeof(struct config_item));
ct->name = strbuf_detach(pair[0], NULL);
if (pair[1]) {
strbuf_trim(pair[1]);
ct->value = strbuf_detach(pair[1], NULL);
}
strbuf_list_free(pair);
lowercase(ct->name);
*config_parameters_tail = ct;
config_parameters_tail = &ct->next;
return 0;
}
int git_config_parse_environment(void) {
int git_config_from_parameters(config_fn_t fn, void *data)
{
const char *env = getenv(CONFIG_DATA_ENVIRONMENT);
char *envw;
const char **argv = NULL;
@@ -92,8 +81,7 @@ int git_config_parse_environment(void) {
}
for (i = 0; i < nr; i++) {
if (git_config_parse_parameter(argv[i]) < 0) {
error("bogus config parameter: %s", argv[i]);
if (git_config_parse_parameter(argv[i], fn, data) < 0) {
free(argv);
free(envw);
return -1;
@@ -102,7 +90,7 @@ int git_config_parse_environment(void) {
free(argv);
free(envw);
return 0;
return nr > 0;
}
static int get_next_char(void)
@@ -583,7 +571,7 @@ static int git_default_core_config(const char *var, const char *value)
if (!strcmp(var, "core.autocrlf")) {
if (value && !strcasecmp(value, "input")) {
if (eol == EOL_CRLF)
if (core_eol == EOL_CRLF)
return error("core.autocrlf=input conflicts with core.eol=crlf");
auto_crlf = AUTO_CRLF_INPUT;
return 0;
@@ -603,14 +591,14 @@ static int git_default_core_config(const char *var, const char *value)
if (!strcmp(var, "core.eol")) {
if (value && !strcasecmp(value, "lf"))
eol = EOL_LF;
core_eol = EOL_LF;
else if (value && !strcasecmp(value, "crlf"))
eol = EOL_CRLF;
core_eol = EOL_CRLF;
else if (value && !strcasecmp(value, "native"))
eol = EOL_NATIVE;
core_eol = EOL_NATIVE;
else
eol = EOL_UNSET;
if (eol == EOL_CRLF && auto_crlf == AUTO_CRLF_INPUT)
core_eol = EOL_UNSET;
if (core_eol == EOL_CRLF && auto_crlf == AUTO_CRLF_INPUT)
return error("core.autocrlf=input conflicts with core.eol=crlf");
return 0;
}
@@ -846,22 +834,6 @@ int git_config_system(void)
return !git_env_bool("GIT_CONFIG_NOSYSTEM", 0);
}
int git_config_from_parameters(config_fn_t fn, void *data)
{
static int loaded_environment;
const struct config_item *ct;
if (!loaded_environment) {
if (git_config_parse_environment() < 0)
return -1;
loaded_environment = 1;
}
for (ct = config_parameters; ct; ct = ct->next)
if (fn(ct->name, ct->value, data) < 0)
return -1;
return 0;
}
int git_config_early(config_fn_t fn, void *data, const char *repo_config)
{
int ret = 0, found = 0;
@@ -891,9 +863,16 @@ int git_config_early(config_fn_t fn, void *data, const char *repo_config)
found += 1;
}
ret += git_config_from_parameters(fn, data);
if (config_parameters)
found += 1;
switch (git_config_from_parameters(fn, data)) {
case -1: /* error */
ret--;
break;
case 0: /* found nothing */
break;
default: /* found at least one item */
found++;
break;
}
return ret == 0 ? found : ret;
}
@@ -1132,12 +1111,12 @@ int git_config_parse_key(const char *key, char **store_key, int *baselen_)
if (last_dot == NULL || last_dot == key) {
error("key does not contain a section: %s", key);
return -2;
return -CONFIG_NO_SECTION_OR_NAME;
}
if (!last_dot[1]) {
error("key does not contain variable name: %s", key);
return -2;
return -CONFIG_NO_SECTION_OR_NAME;
}
baselen = last_dot - key;
@@ -1174,7 +1153,7 @@ int git_config_parse_key(const char *key, char **store_key, int *baselen_)
out_free_ret_1:
free(*store_key);
return -1;
return -CONFIG_INVALID_KEY;
}
/*
@@ -1230,7 +1209,7 @@ int git_config_set_multivar(const char *key, const char *value,
if (fd < 0) {
error("could not lock config file %s: %s", config_filename, strerror(errno));
free(store.key);
ret = -1;
ret = CONFIG_NO_LOCK;
goto out_free;
}
@@ -1244,12 +1223,12 @@ int git_config_set_multivar(const char *key, const char *value,
if ( ENOENT != errno ) {
error("opening %s: %s", config_filename,
strerror(errno));
ret = 3; /* same as "invalid config file" */
ret = CONFIG_INVALID_FILE; /* same as "invalid config file" */
goto out_free;
}
/* if nothing to unset, error out */
if (value == NULL) {
ret = 5;
ret = CONFIG_NOTHING_SET;
goto out_free;
}
@@ -1277,7 +1256,7 @@ int git_config_set_multivar(const char *key, const char *value,
REG_EXTENDED)) {
error("invalid pattern: %s", value_regex);
free(store.value_regex);
ret = 6;
ret = CONFIG_INVALID_PATTERN;
goto out_free;
}
}
@@ -1299,7 +1278,7 @@ int git_config_set_multivar(const char *key, const char *value,
regfree(store.value_regex);
free(store.value_regex);
}
ret = 3;
ret = CONFIG_INVALID_FILE;
goto out_free;
}
@@ -1312,7 +1291,7 @@ int git_config_set_multivar(const char *key, const char *value,
/* if nothing to unset, or too many matches, error out */
if ((store.seen == 0 && value == NULL) ||
(store.seen > 1 && multi_replace == 0)) {
ret = 5;
ret = CONFIG_NOTHING_SET;
goto out_free;
}
@@ -1373,7 +1352,7 @@ int git_config_set_multivar(const char *key, const char *value,
if (commit_lock_file(lock) < 0) {
error("could not commit config file %s", config_filename);
ret = 4;
ret = CONFIG_NO_WRITE;
goto out_free;
}

View File

@@ -18,6 +18,7 @@ bindir = @bindir@
gitexecdir = @libexecdir@/git-core
datarootdir = @datarootdir@
template_dir = @datadir@/git-core/templates
sysconfdir = @sysconfdir@
mandir=@mandir@
@@ -61,6 +62,7 @@ NO_INET_PTON=@NO_INET_PTON@
NO_ICONV=@NO_ICONV@
OLD_ICONV=@OLD_ICONV@
NO_REGEX=@NO_REGEX@
USE_LIBPCRE=@USE_LIBPCRE@
NO_DEFLATE_BOUND=@NO_DEFLATE_BOUND@
INLINE=@INLINE@
SOCKLEN_T=@SOCKLEN_T@

View File

@@ -220,6 +220,27 @@ AS_HELP_STRING([--with-openssl],[use OpenSSL library (default is YES)])
AS_HELP_STRING([], [ARG can be prefix for openssl library and headers]),\
GIT_PARSE_WITH(openssl))
#
# Define USE_LIBPCRE if you have and want to use libpcre. git-grep will be
# able to use Perl-compatible regular expressions.
#
# Define LIBPCREDIR=/foo/bar if your libpcre header and library files are in
# /foo/bar/include and /foo/bar/lib directories.
#
AC_ARG_WITH(libpcre,
AS_HELP_STRING([--with-libpcre],[support Perl-compatible regexes (default is NO)])
AS_HELP_STRING([], [ARG can be also prefix for libpcre library and headers]),
if test "$withval" = "no"; then \
USE_LIBPCRE=; \
elif test "$withval" = "yes"; then \
USE_LIBPCRE=YesPlease; \
else
USE_LIBPCRE=YesPlease; \
LIBPCREDIR=$withval; \
AC_MSG_NOTICE([Setting LIBPCREDIR to $withval]); \
GIT_CONF_APPEND_LINE(LIBPCREDIR=$withval); \
fi \
)
#
# Define NO_CURL if you do not have curl installed. git-http-pull and
# git-http-push are not built, and you cannot use http:// and https://
# transports.
@@ -434,6 +455,25 @@ GIT_UNSTASH_FLAGS($OPENSSLDIR)
AC_SUBST(NEEDS_SSL_WITH_CRYPTO)
AC_SUBST(NO_OPENSSL)
#
# Define USE_LIBPCRE if you have and want to use libpcre. git-grep will be
# able to use Perl-compatible regular expressions.
#
if test -n "$USE_LIBPCRE"; then
GIT_STASH_FLAGS($LIBPCREDIR)
AC_CHECK_LIB([pcre], [pcre_version],
[USE_LIBPCRE=YesPlease],
[USE_LIBPCRE=])
GIT_UNSTASH_FLAGS($LIBPCREDIR)
AC_SUBST(USE_LIBPCRE)
fi
#
# Define NO_CURL if you do not have libcurl installed. git-http-pull and
# git-http-push are not built, and you cannot use http:// and https://

View File

@@ -395,26 +395,28 @@ static int git_use_proxy(const char *host)
return (git_proxy_command && *git_proxy_command);
}
static void git_proxy_connect(int fd[2], char *host)
static struct child_process *git_proxy_connect(int fd[2], char *host)
{
const char *port = STR(DEFAULT_GIT_PORT);
const char *argv[4];
struct child_process proxy;
const char **argv;
struct child_process *proxy;
get_host_and_port(&host, &port);
argv = xmalloc(sizeof(*argv) * 4);
argv[0] = git_proxy_command;
argv[1] = host;
argv[2] = port;
argv[3] = NULL;
memset(&proxy, 0, sizeof(proxy));
proxy.argv = argv;
proxy.in = -1;
proxy.out = -1;
if (start_command(&proxy))
proxy = xcalloc(1, sizeof(*proxy));
proxy->argv = argv;
proxy->in = -1;
proxy->out = -1;
if (start_command(proxy))
die("cannot start proxy %s", argv[0]);
fd[0] = proxy.out; /* read from proxy stdout */
fd[1] = proxy.in; /* write to proxy stdin */
fd[0] = proxy->out; /* read from proxy stdout */
fd[1] = proxy->in; /* write to proxy stdin */
return proxy;
}
#define MAX_CMD_LEN 1024
@@ -455,7 +457,7 @@ struct child_process *git_connect(int fd[2], const char *url_orig,
char *host, *path;
char *end;
int c;
struct child_process *conn;
struct child_process *conn = &no_fork;
enum protocol protocol = PROTO_LOCAL;
int free_path = 0;
char *port = NULL;
@@ -540,7 +542,7 @@ struct child_process *git_connect(int fd[2], const char *url_orig,
*/
char *target_host = xstrdup(host);
if (git_use_proxy(host))
git_proxy_connect(fd, host);
conn = git_proxy_connect(fd, host);
else
git_tcp_connect(fd, host, flags);
/*
@@ -558,7 +560,7 @@ struct child_process *git_connect(int fd[2], const char *url_orig,
free(url);
if (free_path)
free(path);
return &no_fork;
return conn;
}
conn = xcalloc(1, sizeof(*conn));
@@ -607,10 +609,15 @@ struct child_process *git_connect(int fd[2], const char *url_orig,
return conn;
}
int git_connection_is_socket(struct child_process *conn)
{
return conn == &no_fork;
}
int finish_connect(struct child_process *conn)
{
int code;
if (!conn || conn == &no_fork)
if (!conn || git_connection_is_socket(conn))
return 0;
code = finish_command(conn);

View File

@@ -1,6 +1,6 @@
#!bash
#
# bash completion support for core Git.
# bash/zsh completion support for core Git.
#
# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
@@ -18,16 +18,12 @@
# To use these routines:
#
# 1) Copy this file to somewhere (e.g. ~/.git-completion.sh).
# 2) Added the following line to your .bashrc:
# source ~/.git-completion.sh
#
# Or, add the following lines to your .zshrc:
# autoload bashcompinit
# bashcompinit
# 2) Add the following line to your .bashrc/.zshrc:
# source ~/.git-completion.sh
#
# 3) Consider changing your PS1 to also show the current branch:
# PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
# Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
# ZSH: PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '
#
# The argument to __git_ps1 will be displayed only if you
# are currently in a git repository. The %s token will be
@@ -77,6 +73,10 @@
# git@vger.kernel.org
#
if [[ -n ${ZSH_VERSION-} ]]; then
autoload -U +X bashcompinit && bashcompinit
fi
case "$COMP_WORDBREAKS" in
*:*) : great ;;
*) COMP_WORDBREAKS="$COMP_WORDBREAKS:"
@@ -489,12 +489,12 @@ fi
# generates completion reply with compgen
__gitcomp ()
{
local cur
_get_comp_words_by_ref -n =: cur
local cur_="$cur"
if [ $# -gt 2 ]; then
cur="$3"
cur_="$3"
fi
case "$cur" in
case "$cur_" in
--*=)
COMPREPLY=()
;;
@@ -502,7 +502,7 @@ __gitcomp ()
local IFS=$'\n'
COMPREPLY=($(compgen -P "${2-}" \
-W "$(__gitcomp_1 "${1-}" "${4-}")" \
-- "$cur"))
-- "$cur_"))
;;
esac
}
@@ -551,8 +551,7 @@ __git_tags ()
__git_refs ()
{
local i is_hash=y dir="$(__gitdir "${1-}")" track="${2-}"
local cur format refs
_get_comp_words_by_ref -n =: cur
local format refs
if [ -d "$dir" ]; then
case "$cur" in
refs|refs/*)
@@ -629,12 +628,12 @@ __git_refs_remotes ()
__git_remotes ()
{
local i ngoff IFS=$'\n' d="$(__gitdir)"
shopt -q nullglob || ngoff=1
shopt -s nullglob
__git_shopt -q nullglob || ngoff=1
__git_shopt -s nullglob
for i in "$d/remotes"/*; do
echo ${i#$d/remotes/}
done
[ "$ngoff" ] && shopt -u nullglob
[ "$ngoff" ] && __git_shopt -u nullglob
for i in $(git --git-dir="$d" config --get-regexp 'remote\..*\.url' 2>/dev/null); do
i="${i#remote.}"
echo "${i/.url*/}"
@@ -666,19 +665,18 @@ __git_compute_merge_strategies ()
__git_complete_revlist_file ()
{
local pfx ls ref cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
local pfx ls ref cur_="$cur"
case "$cur_" in
*..?*:*)
return
;;
?*:*)
ref="${cur%%:*}"
cur="${cur#*:}"
case "$cur" in
ref="${cur_%%:*}"
cur_="${cur_#*:}"
case "$cur_" in
?*/*)
pfx="${cur%/*}"
cur="${cur##*/}"
pfx="${cur_%/*}"
cur_="${cur_##*/}"
ls="$ref:$pfx"
pfx="$pfx/"
;;
@@ -708,17 +706,17 @@ __git_complete_revlist_file ()
s,$,/,
}
s/^.* //')" \
-- "$cur"))
-- "$cur_"))
;;
*...*)
pfx="${cur%...*}..."
cur="${cur#*...}"
__gitcomp "$(__git_refs)" "$pfx" "$cur"
pfx="${cur_%...*}..."
cur_="${cur_#*...}"
__gitcomp "$(__git_refs)" "$pfx" "$cur_"
;;
*..*)
pfx="${cur%..*}.."
cur="${cur#*..}"
__gitcomp "$(__git_refs)" "$pfx" "$cur"
pfx="${cur_%..*}.."
cur_="${cur_#*..}"
__gitcomp "$(__git_refs)" "$pfx" "$cur_"
;;
*)
__gitcomp "$(__git_refs)"
@@ -739,9 +737,7 @@ __git_complete_revlist ()
__git_complete_remote_or_refspec ()
{
local cur words cword
_get_comp_words_by_ref -n =: cur words cword
local cmd="${words[1]}"
local cur_="$cur" cmd="${words[1]}"
local i c=2 remote="" pfx="" lhs=1 no_complete_refspec=0
while [ $c -lt $cword ]; do
i="${words[c]}"
@@ -771,40 +767,40 @@ __git_complete_remote_or_refspec ()
return
fi
[ "$remote" = "." ] && remote=
case "$cur" in
case "$cur_" in
*:*)
case "$COMP_WORDBREAKS" in
*:*) : great ;;
*) pfx="${cur%%:*}:" ;;
*) pfx="${cur_%%:*}:" ;;
esac
cur="${cur#*:}"
cur_="${cur_#*:}"
lhs=0
;;
+*)
pfx="+"
cur="${cur#+}"
cur_="${cur_#+}"
;;
esac
case "$cmd" in
fetch)
if [ $lhs = 1 ]; then
__gitcomp "$(__git_refs2 "$remote")" "$pfx" "$cur"
__gitcomp "$(__git_refs2 "$remote")" "$pfx" "$cur_"
else
__gitcomp "$(__git_refs)" "$pfx" "$cur"
__gitcomp "$(__git_refs)" "$pfx" "$cur_"
fi
;;
pull)
if [ $lhs = 1 ]; then
__gitcomp "$(__git_refs "$remote")" "$pfx" "$cur"
__gitcomp "$(__git_refs "$remote")" "$pfx" "$cur_"
else
__gitcomp "$(__git_refs)" "$pfx" "$cur"
__gitcomp "$(__git_refs)" "$pfx" "$cur_"
fi
;;
push)
if [ $lhs = 1 ]; then
__gitcomp "$(__git_refs)" "$pfx" "$cur"
__gitcomp "$(__git_refs)" "$pfx" "$cur_"
else
__gitcomp "$(__git_refs "$remote")" "$pfx" "$cur"
__gitcomp "$(__git_refs "$remote")" "$pfx" "$cur_"
fi
;;
esac
@@ -812,8 +808,6 @@ __git_complete_remote_or_refspec ()
__git_complete_strategy ()
{
local cur prev
_get_comp_words_by_ref -n =: cur prev
__git_compute_merge_strategies
case "$prev" in
-s|--strategy)
@@ -991,8 +985,7 @@ __git_aliased_command ()
# __git_find_on_cmdline requires 1 argument
__git_find_on_cmdline ()
{
local word subcommand c=1 words cword
_get_comp_words_by_ref -n =: words cword
local word subcommand c=1
while [ $c -lt $cword ]; do
word="${words[c]}"
for subcommand in $1; do
@@ -1007,8 +1000,7 @@ __git_find_on_cmdline ()
__git_has_doubledash ()
{
local c=1 words cword
_get_comp_words_by_ref -n =: words cword
local c=1
while [ $c -lt $cword ]; do
if [ "--" = "${words[c]}" ]; then
return 0
@@ -1022,8 +1014,7 @@ __git_whitespacelist="nowarn warn error error-all fix"
_git_am ()
{
local cur dir="$(__gitdir)"
_get_comp_words_by_ref -n =: cur
local dir="$(__gitdir)"
if [ -d "$dir"/rebase-apply ]; then
__gitcomp "--skip --continue --resolved --abort"
return
@@ -1047,8 +1038,6 @@ _git_am ()
_git_apply ()
{
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--whitespace=*)
__gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
@@ -1071,8 +1060,6 @@ _git_add ()
{
__git_has_doubledash && return
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--*)
__gitcomp "
@@ -1086,8 +1073,6 @@ _git_add ()
_git_archive ()
{
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--format=*)
__gitcomp "$(git archive --list)" "" "${cur##--format=}"
@@ -1135,9 +1120,8 @@ _git_bisect ()
_git_branch ()
{
local i c=1 only_local_ref="n" has_r="n" cur words cword
local i c=1 only_local_ref="n" has_r="n"
_get_comp_words_by_ref -n =: cur words cword
while [ $c -lt $cword ]; do
i="${words[c]}"
case "$i" in
@@ -1167,8 +1151,6 @@ _git_branch ()
_git_bundle ()
{
local words cword
_get_comp_words_by_ref -n =: words cword
local cmd="${words[2]}"
case "$cword" in
2)
@@ -1191,8 +1173,6 @@ _git_checkout ()
{
__git_has_doubledash && return
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--conflict=*)
__gitcomp "diff3 merge" "" "${cur##--conflict=}"
@@ -1222,8 +1202,6 @@ _git_cherry ()
_git_cherry_pick ()
{
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--*)
__gitcomp "--edit --no-commit"
@@ -1238,8 +1216,6 @@ _git_clean ()
{
__git_has_doubledash && return
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--*)
__gitcomp "--dry-run --quiet"
@@ -1251,8 +1227,6 @@ _git_clean ()
_git_clone ()
{
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--*)
__gitcomp "
@@ -1279,8 +1253,6 @@ _git_commit ()
{
__git_has_doubledash && return
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--cleanup=*)
__gitcomp "default strip verbatim whitespace
@@ -1315,8 +1287,6 @@ _git_commit ()
_git_describe ()
{
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--*)
__gitcomp "
@@ -1348,8 +1318,6 @@ _git_diff ()
{
__git_has_doubledash && return
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--*)
__gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
@@ -1370,8 +1338,6 @@ _git_difftool ()
{
__git_has_doubledash && return
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--tool=*)
__gitcomp "$__git_mergetools_common kompare" "" "${cur##--tool=}"
@@ -1396,8 +1362,6 @@ __git_fetch_options="
_git_fetch ()
{
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--*)
__gitcomp "$__git_fetch_options"
@@ -1409,8 +1373,6 @@ _git_fetch ()
_git_format_patch ()
{
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--thread=*)
__gitcomp "
@@ -1442,8 +1404,6 @@ _git_format_patch ()
_git_fsck ()
{
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--*)
__gitcomp "
@@ -1458,8 +1418,6 @@ _git_fsck ()
_git_gc ()
{
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--*)
__gitcomp "--prune --aggressive"
@@ -1478,15 +1436,14 @@ _git_grep ()
{
__git_has_doubledash && return
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--*)
__gitcomp "
--cached
--text --ignore-case --word-regexp --invert-match
--full-name
--full-name --line-number
--extended-regexp --basic-regexp --fixed-strings
--perl-regexp
--files-with-matches --name-only
--files-without-match
--max-depth
@@ -1502,8 +1459,6 @@ _git_grep ()
_git_help ()
{
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--*)
__gitcomp "--all --info --man --web"
@@ -1521,8 +1476,6 @@ _git_help ()
_git_init ()
{
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--shared=*)
__gitcomp "
@@ -1542,8 +1495,6 @@ _git_ls_files ()
{
__git_has_doubledash && return
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--*)
__gitcomp "--cached --deleted --modified --others --ignored
@@ -1604,8 +1555,6 @@ _git_log ()
if [ -f "$g/MERGE_HEAD" ]; then
merge="--merge"
fi
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--pretty=*)
__gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
@@ -1659,8 +1608,6 @@ _git_merge ()
{
__git_complete_strategy && return
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--*)
__gitcomp "$__git_merge_options"
@@ -1671,8 +1618,6 @@ _git_merge ()
_git_mergetool ()
{
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--tool=*)
__gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}"
@@ -1693,8 +1638,6 @@ _git_merge_base ()
_git_mv ()
{
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--*)
__gitcomp "--dry-run"
@@ -1713,8 +1656,6 @@ _git_notes ()
{
local subcommands='add append copy edit list prune remove show'
local subcommand="$(__git_find_on_cmdline "$subcommands")"
local cur words cword
_get_comp_words_by_ref -n =: cur words cword
case "$subcommand,$cur" in
,--*)
@@ -1764,8 +1705,6 @@ _git_pull ()
{
__git_complete_strategy && return
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--*)
__gitcomp "
@@ -1781,8 +1720,6 @@ _git_pull ()
_git_push ()
{
local cur prev
_get_comp_words_by_ref -n =: cur prev
case "$prev" in
--repo)
__gitcomp "$(__git_remotes)"
@@ -1807,8 +1744,6 @@ _git_push ()
_git_rebase ()
{
local dir="$(__gitdir)"
local cur
_get_comp_words_by_ref -n =: cur
if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
__gitcomp "--continue --skip --abort"
return
@@ -1850,8 +1785,6 @@ __git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all"
_git_send_email ()
{
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--confirm=*)
__gitcomp "
@@ -1893,8 +1826,6 @@ _git_stage ()
__git_config_get_set_variables ()
{
local words cword
_get_comp_words_by_ref -n =: words cword
local prevword word config_file= c=$cword
while [ $c -gt 1 ]; do
word="${words[c]}"
@@ -1925,8 +1856,6 @@ __git_config_get_set_variables ()
_git_config ()
{
local cur prev
_get_comp_words_by_ref -n =: cur prev
case "$prev" in
branch.*.remote)
__gitcomp "$(__git_remotes)"
@@ -2012,70 +1941,60 @@ _git_config ()
return
;;
branch.*.*)
local pfx="${cur%.*}."
cur="${cur##*.}"
__gitcomp "remote merge mergeoptions rebase" "$pfx" "$cur"
local pfx="${cur%.*}." cur_="${cur##*.}"
__gitcomp "remote merge mergeoptions rebase" "$pfx" "$cur_"
return
;;
branch.*)
local pfx="${cur%.*}."
cur="${cur#*.}"
__gitcomp "$(__git_heads)" "$pfx" "$cur" "."
local pfx="${cur%.*}." cur_="${cur#*.}"
__gitcomp "$(__git_heads)" "$pfx" "$cur_" "."
return
;;
guitool.*.*)
local pfx="${cur%.*}."
cur="${cur##*.}"
local pfx="${cur%.*}." cur_="${cur##*.}"
__gitcomp "
argprompt cmd confirm needsfile noconsole norescan
prompt revprompt revunmerged title
" "$pfx" "$cur"
" "$pfx" "$cur_"
return
;;
difftool.*.*)
local pfx="${cur%.*}."
cur="${cur##*.}"
__gitcomp "cmd path" "$pfx" "$cur"
local pfx="${cur%.*}." cur_="${cur##*.}"
__gitcomp "cmd path" "$pfx" "$cur_"
return
;;
man.*.*)
local pfx="${cur%.*}."
cur="${cur##*.}"
__gitcomp "cmd path" "$pfx" "$cur"
local pfx="${cur%.*}." cur_="${cur##*.}"
__gitcomp "cmd path" "$pfx" "$cur_"
return
;;
mergetool.*.*)
local pfx="${cur%.*}."
cur="${cur##*.}"
__gitcomp "cmd path trustExitCode" "$pfx" "$cur"
local pfx="${cur%.*}." cur_="${cur##*.}"
__gitcomp "cmd path trustExitCode" "$pfx" "$cur_"
return
;;
pager.*)
local pfx="${cur%.*}."
cur="${cur#*.}"
local pfx="${cur%.*}." cur_="${cur#*.}"
__git_compute_all_commands
__gitcomp "$__git_all_commands" "$pfx" "$cur"
__gitcomp "$__git_all_commands" "$pfx" "$cur_"
return
;;
remote.*.*)
local pfx="${cur%.*}."
cur="${cur##*.}"
local pfx="${cur%.*}." cur_="${cur##*.}"
__gitcomp "
url proxy fetch push mirror skipDefaultUpdate
receivepack uploadpack tagopt pushurl
" "$pfx" "$cur"
" "$pfx" "$cur_"
return
;;
remote.*)
local pfx="${cur%.*}."
cur="${cur#*.}"
__gitcomp "$(__git_remotes)" "$pfx" "$cur" "."
local pfx="${cur%.*}." cur_="${cur#*.}"
__gitcomp "$(__git_remotes)" "$pfx" "$cur_" "."
return
;;
url.*.*)
local pfx="${cur%.*}."
cur="${cur##*.}"
__gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur"
local pfx="${cur%.*}." cur_="${cur##*.}"
__gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur_"
return
;;
esac
@@ -2396,8 +2315,6 @@ _git_reset ()
{
__git_has_doubledash && return
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--*)
__gitcomp "--merge --mixed --hard --soft --patch"
@@ -2409,8 +2326,6 @@ _git_reset ()
_git_revert ()
{
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--*)
__gitcomp "--edit --mainline --no-edit --no-commit --signoff"
@@ -2424,8 +2339,6 @@ _git_rm ()
{
__git_has_doubledash && return
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--*)
__gitcomp "--cached --dry-run --ignore-unmatch --quiet"
@@ -2439,8 +2352,6 @@ _git_shortlog ()
{
__git_has_doubledash && return
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--*)
__gitcomp "
@@ -2458,8 +2369,6 @@ _git_show ()
{
__git_has_doubledash && return
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--pretty=*)
__gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
@@ -2483,8 +2392,6 @@ _git_show ()
_git_show_branch ()
{
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--*)
__gitcomp "
@@ -2501,8 +2408,6 @@ _git_show_branch ()
_git_stash ()
{
local cur
_get_comp_words_by_ref -n =: cur
local save_opts='--keep-index --no-keep-index --quiet --patch'
local subcommands='save list show apply clear drop pop create branch'
local subcommand="$(__git_find_on_cmdline "$subcommands")"
@@ -2547,8 +2452,6 @@ _git_submodule ()
local subcommands="add status init update summary foreach sync"
if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then
local cur
_get_comp_words_by_ref -n =: cur
case "$cur" in
--*)
__gitcomp "--quiet --cached"
@@ -2592,8 +2495,6 @@ _git_svn ()
--edit --rmdir --find-copies-harder --copy-similarity=
"
local cur
_get_comp_words_by_ref -n =: cur
case "$subcommand,$cur" in
fetch,--*)
__gitcomp "--revision= --fetch-all $fc_opts"
@@ -2665,8 +2566,6 @@ _git_svn ()
_git_tag ()
{
local i c=1 f=0
local words cword prev
_get_comp_words_by_ref -n =: words cword prev
while [ $c -lt $cword ]; do
i="${words[c]}"
case "$i" in
@@ -2710,10 +2609,14 @@ _git ()
if [[ -n ${ZSH_VERSION-} ]]; then
emulate -L bash
setopt KSH_TYPESET
# workaround zsh's bug that leaves 'words' as a special
# variable in versions < 4.3.12
typeset -h words
fi
local cur words cword
_get_comp_words_by_ref -n =: cur words cword
local cur words cword prev
_get_comp_words_by_ref -n =: cur words cword prev
while [ $c -lt $cword ]; do
i="${words[c]}"
case "$i" in
@@ -2761,17 +2664,22 @@ _gitk ()
if [[ -n ${ZSH_VERSION-} ]]; then
emulate -L bash
setopt KSH_TYPESET
# workaround zsh's bug that leaves 'words' as a special
# variable in versions < 4.3.12
typeset -h words
fi
local cur words cword prev
_get_comp_words_by_ref -n =: cur words cword prev
__git_has_doubledash && return
local cur
local g="$(__gitdir)"
local merge=""
if [ -f "$g/MERGE_HEAD" ]; then
merge="--merge"
fi
_get_comp_words_by_ref -n =: cur
case "$cur" in
--*)
__gitcomp "
@@ -2800,7 +2708,7 @@ complete -o bashdefault -o default -o nospace -F _git git.exe 2>/dev/null \
fi
if [[ -n ${ZSH_VERSION-} ]]; then
shopt () {
__git_shopt () {
local option
if [ $# -ne 2 ]; then
echo "USAGE: $0 (-q|-s|-u) <option>" >&2
@@ -2823,4 +2731,8 @@ if [[ -n ${ZSH_VERSION-} ]]; then
return 1
esac
}
else
__git_shopt () {
shopt "$@"
}
fi

Some files were not shown because too many files have changed in this diff Show More