Compare commits
25 Commits
v1.7.8-rc0
...
v1.7.6.6
Author | SHA1 | Date | |
---|---|---|---|
f174a2583c | |||
28b22f8af9 | |||
04f6785a08 | |||
15f07e061e | |||
37475f97d1 | |||
592ed5673e | |||
f14f9803ef | |||
b6fb7fed6a | |||
c432ef996e | |||
909ca7b9ac | |||
77f7f82288 | |||
1afca44495 | |||
07b88a00c0 | |||
5c951ef47b | |||
0eddcbf161 | |||
15b7898c5e | |||
52b195f2b8 | |||
43176d1e4c | |||
6d1cdadbee | |||
c3ea051544 | |||
5914f2d057 | |||
c2857fb8b7 | |||
332de7a1c8 | |||
74b531f65f | |||
e8b14d7e3f |
@ -1,12 +1,12 @@
|
||||
MAN1_TXT= \
|
||||
$(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \
|
||||
$(wildcard git-*.txt)) \
|
||||
gitk.txt gitweb.txt git.txt
|
||||
gitk.txt git.txt
|
||||
MAN5_TXT=gitattributes.txt gitignore.txt gitmodules.txt githooks.txt \
|
||||
gitrepository-layout.txt gitweb.conf.txt
|
||||
gitrepository-layout.txt
|
||||
MAN7_TXT=gitcli.txt gittutorial.txt gittutorial-2.txt \
|
||||
gitcvs-migration.txt gitcore-tutorial.txt gitglossary.txt \
|
||||
gitdiffcore.txt gitnamespaces.txt gitrevisions.txt gitworkflows.txt
|
||||
gitdiffcore.txt gitrevisions.txt gitworkflows.txt
|
||||
|
||||
MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)
|
||||
MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT))
|
||||
|
26
Documentation/RelNotes/1.7.6.5.txt
Normal file
26
Documentation/RelNotes/1.7.6.5.txt
Normal file
@ -0,0 +1,26 @@
|
||||
Git v1.7.6.5 Release Notes
|
||||
==========================
|
||||
|
||||
Fixes since v1.7.6.4
|
||||
--------------------
|
||||
|
||||
* The date parser did not accept timezone designators that lack minutes
|
||||
part and also has a colon between "hh:mm".
|
||||
|
||||
* After fetching from a remote that has very long refname, the reporting
|
||||
output could have corrupted by overrunning a static buffer.
|
||||
|
||||
* "git mergetool" did not use its arguments as pathspec, but as a path to
|
||||
the file that may not even have any conflict.
|
||||
|
||||
* "git name-rev --all" tried to name all _objects_, naturally failing to
|
||||
describe many blobs and trees, instead of showing only commits as
|
||||
advertised in its documentation.
|
||||
|
||||
* "git remote rename $a $b" were not careful to match the remote name
|
||||
against $a (i.e. source side of the remote nickname).
|
||||
|
||||
* "gitweb" used to produce a non-working link while showing the contents
|
||||
of a blob, when JavaScript actions are enabled.
|
||||
|
||||
Also contains minor fixes and documentation updates.
|
16
Documentation/RelNotes/1.7.6.6.txt
Normal file
16
Documentation/RelNotes/1.7.6.6.txt
Normal file
@ -0,0 +1,16 @@
|
||||
Git v1.7.6.6 Release Notes
|
||||
==========================
|
||||
|
||||
Fixes since v1.7.6.5
|
||||
--------------------
|
||||
|
||||
* The code to look up attributes for paths reused entries from a wrong
|
||||
directory when two paths in question are in adjacent directories and
|
||||
the name of the one directory is a prefix of the other.
|
||||
|
||||
* When producing a "thin pack" (primarily used in bundles and smart
|
||||
HTTP transfers) out of a fully packed repository, we unnecessarily
|
||||
avoided sending recent objects as a delta against objects we know
|
||||
the other side has.
|
||||
|
||||
Also contains minor fixes and documentation updates.
|
@ -1,60 +0,0 @@
|
||||
Git v1.7.7.1 Release Notes
|
||||
==========================
|
||||
|
||||
Fixes since v1.7.7
|
||||
------------------
|
||||
|
||||
* On some BSD systems, adding +s bit on directories is detrimental
|
||||
(it is not necessary on BSD to begin with). "git init --shared"
|
||||
has been updated to take this into account without extra makefile
|
||||
settings on platforms the Makefile knows about.
|
||||
|
||||
* After incorrectly written third-party tools store a tag object in
|
||||
HEAD, git diagnosed it as a repository corruption and refused to
|
||||
proceed in order to avoid spreading the damage. We now gracefully
|
||||
recover from such a situation by pretending as if the commit that
|
||||
is pointed at by the tag were in HEAD.
|
||||
|
||||
* "git apply --whitespace=error" did not bother to report the exact
|
||||
line number in the patch that introduced new blank lines at the end
|
||||
of the file.
|
||||
|
||||
* "git apply --index" did not check corrupted patch.
|
||||
|
||||
* "git checkout $tree $directory/" resurrected paths locally removed or
|
||||
modified only in the working tree in $directory/ that did not appear
|
||||
in $directory of the given $tree. They should have been kept intact.
|
||||
|
||||
* "git diff $tree $path" used to apply the pathspec at the output stage,
|
||||
reading the whole tree, wasting resources.
|
||||
|
||||
* The code to check for updated submodules during a "git fetch" of the
|
||||
superproject had an unnecessary quadratic loop.
|
||||
|
||||
* "git fetch" from a large bundle did not enable the progress output.
|
||||
|
||||
* When "git fsck --lost-and-found" found that an empty blob object in the
|
||||
object store is unreachable, it incorrectly reported an error after
|
||||
writing the lost blob out successfully.
|
||||
|
||||
* "git filter-branch" did not refresh the index before checking that the
|
||||
working tree was clean.
|
||||
|
||||
* "git grep $tree" when run with multiple threads had an unsafe access to
|
||||
the object database that should have been protected with mutex.
|
||||
|
||||
* The "--ancestry-path" option to "git log" and friends misbehaved in a
|
||||
history with complex criss-cross merges and showed an uninteresting
|
||||
side history as well.
|
||||
|
||||
* Test t1304 assumed LOGNAME is always set, which may not be true on
|
||||
some systems.
|
||||
|
||||
* Tests with --valgrind failed to find "mergetool" scriptlets.
|
||||
|
||||
* "git patch-id" miscomputed the patch-id in a patch that has a line longer
|
||||
than 1kB.
|
||||
|
||||
* When an "exec" insn failed after modifying the index and/or the working
|
||||
tree during "rebase -i", we now check and warn that the changes need to
|
||||
be cleaned up.
|
@ -1,134 +0,0 @@
|
||||
Git v1.7.7 Release Notes
|
||||
========================
|
||||
|
||||
Updates since v1.7.6
|
||||
--------------------
|
||||
|
||||
* The scripting part of the codebase is getting prepared for i18n/l10n.
|
||||
|
||||
* Interix, Cygwin and Minix ports got updated.
|
||||
|
||||
* Various updates to git-p4 (in contrib/), fast-import, and git-svn.
|
||||
|
||||
* Gitweb learned to read from /etc/gitweb-common.conf when it exists,
|
||||
before reading from gitweb_config.perl or from /etc/gitweb.conf
|
||||
(this last one is read only when per-repository gitweb_config.perl
|
||||
does not exist).
|
||||
|
||||
* Various codepaths that invoked zlib deflate/inflate assumed that these
|
||||
functions can compress or uncompress more than 4GB data in one call on
|
||||
platforms with 64-bit long, which has been corrected.
|
||||
|
||||
* Git now recognizes loose objects written by other implementations that
|
||||
use a non-standard window size for zlib deflation (e.g. Agit running on
|
||||
Android with 4kb window). We used to reject anything that was not
|
||||
deflated with 32kb window.
|
||||
|
||||
* Interaction between the use of pager and coloring of the output has
|
||||
been improved, especially when a command that is not built-in was
|
||||
involved.
|
||||
|
||||
* "git am" learned to pass the "--exclude=<path>" option through to underlying
|
||||
"git apply".
|
||||
|
||||
* You can now feed many empty lines before feeding an mbox file to
|
||||
"git am".
|
||||
|
||||
* "git archive" can be told to pass the output to gzip compression and
|
||||
produce "archive.tar.gz".
|
||||
|
||||
* "git bisect" can be used in a bare repository (provided that the test
|
||||
you perform per each iteration does not need a working tree, of
|
||||
course).
|
||||
|
||||
* The length of abbreviated object names in "git branch -v" output
|
||||
now honors the core.abbrev configuration variable.
|
||||
|
||||
* "git check-attr" can take relative paths from the command line.
|
||||
|
||||
* "git check-attr" learned an "--all" option to list the attributes for a
|
||||
given path.
|
||||
|
||||
* "git checkout" (both the code to update the files upon checking out a
|
||||
different branch and the code to checkout a specific set of files) learned
|
||||
to stream the data from object store when possible, without having to
|
||||
read the entire contents of a file into memory first. An earlier round
|
||||
of this code that is not in any released version had a large leak but
|
||||
now it has been plugged.
|
||||
|
||||
* "git clone" can now take a "--config key=value" option to set the
|
||||
repository configuration options that affect the initial checkout.
|
||||
|
||||
* "git commit <paths>..." now lets you feed relative pathspecs that
|
||||
refer to outside your current subdirectory.
|
||||
|
||||
* "git diff --stat" learned a --stat-count option to limit the output of
|
||||
a diffstat report.
|
||||
|
||||
* "git diff" learned a "--histogram" option to use a different diff
|
||||
generation machinery stolen from jgit, which might give better
|
||||
performance.
|
||||
|
||||
* "git diff" had a weird worst case behaviour that can be triggered
|
||||
when comparing files with potentially many places that could match.
|
||||
|
||||
* "git fetch", "git push" and friends no longer show connection
|
||||
errors for addresses that couldn't be connected to when at least one
|
||||
address succeeds (this is arguably a regression but a deliberate
|
||||
one).
|
||||
|
||||
* "git grep" learned "--break" and "--heading" options, to let users mimic
|
||||
the output format of "ack".
|
||||
|
||||
* "git grep" learned a "-W" option that shows wider context using the same
|
||||
logic used by "git diff" to determine the hunk header.
|
||||
|
||||
* Invoking the low-level "git http-fetch" without "-a" option (which
|
||||
git itself never did---normal users should not have to worry about
|
||||
this) is now deprecated.
|
||||
|
||||
* The "--decorate" option to "git log" and its family learned to
|
||||
highlight grafted and replaced commits.
|
||||
|
||||
* "git rebase master topci" no longer spews usage hints after giving
|
||||
the "fatal: no such branch: topci" error message.
|
||||
|
||||
* The recursive merge strategy implementation got a fairly large
|
||||
fix for many corner cases that may rarely happen in real world
|
||||
projects (it has been verified that none of the 16000+ merges in
|
||||
the Linux kernel history back to v2.6.12 is affected with the
|
||||
corner case bugs this update fixes).
|
||||
|
||||
* "git stash" learned an "--include-untracked option".
|
||||
|
||||
* "git submodule update" used to stop at the first error updating a
|
||||
submodule; it now goes on to update other submodules that can be
|
||||
updated, and reports the ones with errors at the end.
|
||||
|
||||
* "git push" can be told with the "--recurse-submodules=check" option to
|
||||
refuse pushing of the supermodule, if any of its submodules'
|
||||
commits hasn't been pushed out to their remotes.
|
||||
|
||||
* "git upload-pack" and "git receive-pack" learned to pretend that only a
|
||||
subset of the refs exist in a repository. This may help a site to
|
||||
put many tiny repositories into one repository (this would not be
|
||||
useful for larger repositories as repacking would be problematic).
|
||||
|
||||
* "git verify-pack" has been rewritten to use the "index-pack" machinery
|
||||
that is more efficient in reading objects in packfiles.
|
||||
|
||||
* test scripts for gitweb tried to run even when CGI-related perl modules
|
||||
are not installed; they now exit early when the latter are unavailable.
|
||||
|
||||
Also contains various documentation updates and minor miscellaneous
|
||||
changes.
|
||||
|
||||
|
||||
Fixes since v1.7.6
|
||||
------------------
|
||||
|
||||
Unless otherwise noted, all fixes in the 1.7.6.X maintenance track are
|
||||
included in this release.
|
||||
|
||||
* "git branch -m" and "git checkout -b" incorrectly allowed the tip
|
||||
of the branch that is currently checked out updated.
|
@ -1,221 +0,0 @@
|
||||
Git v1.7.8 Release Notes (draft)
|
||||
================================
|
||||
|
||||
Updates since v1.7.7
|
||||
--------------------
|
||||
|
||||
* Some git-svn, git-gui, git-p4 (in contrib) and msysgit updates.
|
||||
|
||||
* Updates to bash completion scripts.
|
||||
|
||||
* The build procedure has been taught to take advantage of computed
|
||||
dependency automatically when the complier supports it.
|
||||
|
||||
* The date parser now accepts timezone designators that lack minutes
|
||||
part and also has a colon between "hh:mm".
|
||||
|
||||
* The contents of the /etc/mailname file, if exists, is used as the
|
||||
default value of the hostname part of the committer/author e-mail.
|
||||
|
||||
* "git am" learned how to read from patches generated by Hg.
|
||||
|
||||
* "git archive" talking with a remote repository can report errors
|
||||
from the remote side in a more informative way.
|
||||
|
||||
* "git branch" learned an explicit --list option to ask for branches
|
||||
listed, optionally with a glob matching pattern to limit its output.
|
||||
|
||||
* "git check-attr" learned "--cached" option to look at .gitattributes
|
||||
files from the index, not from the working tree.
|
||||
|
||||
* Variants of "git cherry-pick" and "git revert" that take multiple
|
||||
commits learned to "--continue".
|
||||
|
||||
* "git daemon" gives more human readble error messages to clients
|
||||
using ERR packets when appropriate.
|
||||
|
||||
* Errors at the network layer is logged by "git daemon".
|
||||
|
||||
* "git diff" learned "--minimal" option to spend extra cycles to come
|
||||
up with a minimal patch output.
|
||||
|
||||
* "git diff" learned "--function-context" option to show the whole
|
||||
function as context that was affected by a change.
|
||||
|
||||
* "git difftool" can be told to skip launching the tool for a path by
|
||||
answering 'n' to its prompt.
|
||||
|
||||
* "git fetch" learned to honor transfer.fsckobjects configuration to
|
||||
validate the objects that were received from the other end, just like
|
||||
"git receive-pack" (the receiving end of "git push") does.
|
||||
|
||||
* "git fetch" makes sure that the set of objects it received from the
|
||||
other end actually completes the history before updating the refs.
|
||||
"git receive-pack" (the receiving end of "git push") learned to do the
|
||||
same.
|
||||
|
||||
* "git fetch" learned that fetching/cloning from a regular file on the
|
||||
filesystem is not necessarily a request to unpack a bundle file; the
|
||||
file could be ".git" with "gitdir: <path>" in it.
|
||||
|
||||
* "git for-each-ref" learned "%(contents:subject)", "%(contents:body)"
|
||||
and "%(contents:signature)". The last one is useful for signed tags.
|
||||
|
||||
* "git grep" used to incorrectly pay attention to .gitignore files
|
||||
scattered in the directory it was working in even when "--no-index"
|
||||
option was used. It no longer does this. The "--exclude-standard"
|
||||
option needs to be given to explicitly activate the ignore
|
||||
mechanism.
|
||||
|
||||
* "git grep" learned "--untracked" option, where given patterns are
|
||||
searched in untracked (but not ignored) files as well as tracked
|
||||
files in the working tree, so that matches in new but not yet
|
||||
added files do not get missed.
|
||||
|
||||
* The recursive merge backend no longer looks for meaningless
|
||||
existing merges in submodules unless in the outermost merge.
|
||||
|
||||
* "git log" and friends learned "--children" option.
|
||||
|
||||
* "git ls-remote" learned to respond to "-h"(elp) requests.
|
||||
|
||||
* "git merge" learned the "--edit" option to allow users to edit the
|
||||
merge commit log message.
|
||||
|
||||
* "git rebase -i" can be told to use special purpose editor suitable
|
||||
only for its insn sheet via sequence.editor configuration variable.
|
||||
|
||||
* "git send-email" learned to respond to "-h"(elp) requests.
|
||||
|
||||
* "git send-email" allows the value given to sendemail.aliasfile to begin
|
||||
with "~/" to refer to the $HOME directory.
|
||||
|
||||
* "git send-email" forces use of Authen::SASL::Perl to work around
|
||||
issues between Authen::SASL::Cyrus and AUTH PLAIN/LOGIN.
|
||||
|
||||
* "git stash" learned "--include-untracked" option to stash away
|
||||
untracked/ignored cruft from the working tree.
|
||||
|
||||
* "git submodule clone" does not leak an error message to the UI
|
||||
level unnecessarily anymore.
|
||||
|
||||
* "git submodule update" learned to honor "none" as the value for
|
||||
submodule.<name>.update to specify that the named submodule should
|
||||
not be checked out by default.
|
||||
|
||||
* When populating a new submodule directory with "git submodule init",
|
||||
the $GIT_DIR metainformation directory for submodules is created inside
|
||||
$GIT_DIR/modules/<name>/ directory of the superproject and referenced
|
||||
via the gitfile mechanism. This is to make it possible to switch
|
||||
between commits in the superproject that has and does not have the
|
||||
submodule in the tree without re-cloning.
|
||||
|
||||
* "mediawiki" remote helper can interact with (surprise!) MediaWiki
|
||||
with "git fetch" & "git push".
|
||||
|
||||
* "gitweb" leaked unescaped control characters from syntax hiliter
|
||||
outputs.
|
||||
|
||||
* "gitweb" can be told to give custom string at the end of the HTML
|
||||
HEAD element.
|
||||
|
||||
* "gitweb" now has its own manual pages.
|
||||
|
||||
|
||||
Also contains other documentation updates and minor code cleanups.
|
||||
|
||||
|
||||
Fixes since v1.7.7
|
||||
------------------
|
||||
|
||||
Unless otherwise noted, all fixes in the 1.7.7.X maintenance track are
|
||||
included in this release.
|
||||
|
||||
* We used to drop error messages from libcurl on certain kinds of
|
||||
errors.
|
||||
(merge be22d92eac8 jn/maint-http-error-message later to maint).
|
||||
|
||||
* Error report from smart HTTP transport, when the connection was
|
||||
broken in the middle of a transfer, showed a useless message on
|
||||
a corrupt packet.
|
||||
(merge 6cdf022 sp/smart-http-failure later to maint).
|
||||
|
||||
* HTTP transport did not use pushurl correctly, and also did not tell
|
||||
what host it is trying to authenticate with when asking for
|
||||
credentials.
|
||||
(merge deba493 jk/http-auth later to maint).
|
||||
|
||||
* "git branch -m/-M" advertised to update RENAME_REF ref in the
|
||||
commit log message that introduced the feature but not anywhere in
|
||||
the documentation, and never did update such a ref anyway. This
|
||||
undocumented misfeature that did not exist has been excised.
|
||||
(merge b0eab01 jc/maint-remove-renamed-ref later to maint).
|
||||
|
||||
* Adding many refs to the local repository in one go (e.g. "git fetch"
|
||||
that fetches many tags) and looking up a ref by name in a repository
|
||||
with too many refs were unnecessarily slow.
|
||||
(merge 17d68a54d jp/get-ref-dir-unsorted later to maint).
|
||||
|
||||
* "git fetch --prune" was unsafe when used with refspecs from the
|
||||
command line.
|
||||
(merge e8c1e6c cn/fetch-prune later to maint).
|
||||
|
||||
* Report from "git commit" on untracked files was confused under
|
||||
core.ignorecase option.
|
||||
(merge 2548183b jk/name-hash-dirent later to maint).
|
||||
|
||||
* The attribute mechanism did not use case insensitive match when
|
||||
core.ignorecase was set.
|
||||
(merge 6eba621 bc/attr-ignore-case later to maint).
|
||||
|
||||
* "git bisect" did not notice when it failed to update the working tree
|
||||
to the next commit to be tested.
|
||||
(merge 1acf11717 js/bisect-no-checkout later to maint).
|
||||
|
||||
* "git config --bool --get-regexp" failed to separate the variable name
|
||||
and its value "true" when the variable is defined without "= true".
|
||||
(merge 880e3cc mm/maint-config-explicit-bool-display later to maint).
|
||||
|
||||
* "git remote rename $a $b" were not careful to match the remote name
|
||||
against $a (i.e. source side of the remote nickname).
|
||||
(merge b52d00aed mz/remote-rename later to maint).
|
||||
|
||||
* "git diff --[num]stat" used to use the number of lines of context
|
||||
different from the default, potentially giving different results from
|
||||
"git diff | diffstat" and confusing the users.
|
||||
(merge f01cae918 jc/maint-diffstat-numstat-context later to maint).
|
||||
|
||||
* "git merge" did not understand ":/<pattern>" as a way to name a commit.
|
||||
|
||||
* "git mergetool" learned to use its arguments as pathspec, not a path to
|
||||
the file that may not even have any conflict.
|
||||
(merge 6d9990a jm/mergetool-pathspec later to maint).
|
||||
|
||||
* "git pull" and "git rebase" did not work well even when GIT_WORK_TREE is
|
||||
set correctly with GIT_DIR if the current directory is outside the working
|
||||
tree.
|
||||
(merge 035b5bf jk/pull-rebase-with-work-tree later to maint).
|
||||
|
||||
" "git push" on the receiving end used to call post-receive and post-update
|
||||
hooks for attempted removal of non-existing refs.
|
||||
(merge 160b81ed ph/push-to-delete-nothing later to maint).
|
||||
|
||||
* "git send-email" did not honor the configured hostname when restarting
|
||||
the HELO/EHLO exchange after switching TLS on.
|
||||
(merge 155b940 md/smtp-tls-hello-again later to maint).
|
||||
|
||||
* "gitweb" used to produce a non-working link while showing the contents
|
||||
of a blob, when JavaScript actions are enabled.
|
||||
(merge 2b07ff3ff ps/gitweb-js-with-lineno later to maint).
|
||||
|
||||
* The logic to filter out forked projects in the project list in
|
||||
"gitweb" was broken for some time.
|
||||
(merge 53c632f jm/maint-gitweb-filter-forks-fix later to maint).
|
||||
|
||||
---
|
||||
exec >/var/tmp/1
|
||||
O=v1.7.7.1-492-g324bc2a
|
||||
echo O=$(git describe --always master)
|
||||
git log --first-parent --oneline --reverse ^$O master
|
||||
echo
|
||||
git shortlog --no-merges ^$O master
|
@ -117,4 +117,5 @@ commit. And the default value is 40. If there are more than one
|
||||
take effect.
|
||||
|
||||
-h::
|
||||
--help::
|
||||
Show help message.
|
||||
|
@ -45,10 +45,9 @@ lines. Variables may belong directly to a section or to a given subsection.
|
||||
You can have `[section]` if you have `[section "subsection"]`, but you
|
||||
don't need to.
|
||||
|
||||
There is also a deprecated `[section.subsection]` syntax. With this
|
||||
syntax, the subsection name is converted to lower-case and is also
|
||||
compared case sensitively. These subsection names follow the same
|
||||
restrictions as section names.
|
||||
There is also a case insensitive alternative `[section.subsection]` syntax.
|
||||
In this syntax, subsection names follow the same restrictions as for section
|
||||
names.
|
||||
|
||||
All the other lines (and the remainder of the line after the section
|
||||
header) are recognized as setting variables, in the form
|
||||
@ -148,7 +147,7 @@ advice.*::
|
||||
|
||||
core.fileMode::
|
||||
If false, the executable bit differences between the index and
|
||||
the working tree are ignored; useful on broken filesystems like FAT.
|
||||
the working copy are ignored; useful on broken filesystems like FAT.
|
||||
See linkgit:git-update-index[1].
|
||||
+
|
||||
The default is true, except linkgit:git-clone[1] or linkgit:git-init[1]
|
||||
@ -180,7 +179,7 @@ is created.
|
||||
|
||||
core.trustctime::
|
||||
If false, the ctime differences between the index and the
|
||||
working tree are ignored; useful when the inode change time
|
||||
working copy are ignored; useful when the inode change time
|
||||
is regularly modified by something outside Git (file system
|
||||
crawlers and some backup systems).
|
||||
See linkgit:git-update-index[1]. True by default.
|
||||
@ -293,7 +292,7 @@ core.ignoreStat::
|
||||
If true, commands which modify both the working tree and the index
|
||||
will mark the updated paths with the "assume unchanged" bit in the
|
||||
index. These marked files are then assumed to stay unchanged in the
|
||||
working tree, until you mark them otherwise manually - Git will not
|
||||
working copy, until you mark them otherwise manually - Git will not
|
||||
detect the file changes by lstat() calls. This is useful on systems
|
||||
where those are very slow, such as Microsoft Windows.
|
||||
See linkgit:git-update-index[1].
|
||||
@ -474,12 +473,6 @@ core.editor::
|
||||
variable when it is set, and the environment variable
|
||||
`GIT_EDITOR` is not set. See linkgit:git-var[1].
|
||||
|
||||
sequence.editor::
|
||||
Text editor used by `git rebase -i` for editing the rebase insn file.
|
||||
The value is meant to be interpreted by the shell when it is used.
|
||||
It can be overridden by the `GIT_SEQUENCE_EDITOR` environment variable.
|
||||
When not configured the default commit message editor is used instead.
|
||||
|
||||
core.pager::
|
||||
The command that git will use to paginate output. Can
|
||||
be overridden with the `GIT_PAGER` environment
|
||||
@ -864,13 +857,6 @@ fetch.recurseSubmodules::
|
||||
when its superproject retrieves a commit that updates the submodule's
|
||||
reference.
|
||||
|
||||
fetch.fsckObjects::
|
||||
If it is set to true, git-fetch-pack will check all fetched
|
||||
objects. It will abort in the case of a malformed object or a
|
||||
broken link. The result of an abort are only dangling objects.
|
||||
Defaults to false. If not set, the value of `transfer.fsckObjects`
|
||||
is used instead.
|
||||
|
||||
fetch.unpackLimit::
|
||||
If the number of objects fetched over the git native
|
||||
transfer is below this
|
||||
@ -1078,23 +1064,6 @@ All gitcvs variables except for 'gitcvs.usecrlfattr' and
|
||||
is one of "ext" and "pserver") to make them apply only for the given
|
||||
access method.
|
||||
|
||||
gitweb.category::
|
||||
gitweb.description::
|
||||
gitweb.owner::
|
||||
gitweb.url::
|
||||
See linkgit:gitweb[1] for description.
|
||||
|
||||
gitweb.avatar::
|
||||
gitweb.blame::
|
||||
gitweb.grep::
|
||||
gitweb.highlight::
|
||||
gitweb.patches::
|
||||
gitweb.pickaxe::
|
||||
gitweb.remote_heads::
|
||||
gitweb.showsizes::
|
||||
gitweb.snapshot::
|
||||
See linkgit:gitweb.conf[5] for description.
|
||||
|
||||
grep.lineNumber::
|
||||
If set to true, enable '-n' option by default.
|
||||
|
||||
@ -1229,14 +1198,6 @@ http.proxy::
|
||||
environment variable (see linkgit:curl[1]). This can be overridden
|
||||
on a per-remote basis; see remote.<name>.proxy
|
||||
|
||||
http.cookiefile::
|
||||
File containing previously stored cookie lines which should be used
|
||||
in the git http session, if they match the server. The file format
|
||||
of the file to read cookies from should be plain HTTP headers or
|
||||
the Netscape/Mozilla cookie file format (see linkgit:curl[1]).
|
||||
NOTE that the file specified with http.cookiefile is only used as
|
||||
input. No cookies will be stored in the file.
|
||||
|
||||
http.sslVerify::
|
||||
Whether to verify the SSL certificate when fetching or pushing
|
||||
over HTTPS. Can be overridden by the 'GIT_SSL_NO_VERIFY' environment
|
||||
@ -1627,8 +1588,7 @@ receive.fsckObjects::
|
||||
If it is set to true, git-receive-pack will check all received
|
||||
objects. It will abort in the case of a malformed object or a
|
||||
broken link. The result of an abort are only dangling objects.
|
||||
Defaults to false. If not set, the value of `transfer.fsckObjects`
|
||||
is used instead.
|
||||
Defaults to false.
|
||||
|
||||
receive.unpackLimit::
|
||||
If the number of objects received in a push is below this
|
||||
@ -1740,10 +1700,11 @@ rerere.autoupdate::
|
||||
|
||||
rerere.enabled::
|
||||
Activate recording of resolved conflicts, so that identical
|
||||
conflict hunks can be resolved automatically, should they
|
||||
be encountered again. linkgit:git-rerere[1] command is by
|
||||
default enabled if you create `rr-cache` directory under
|
||||
`$GIT_DIR`, but can be disabled by setting this option to false.
|
||||
conflict hunks can be resolved automatically, should they be
|
||||
encountered again. By default, linkgit:git-rerere[1] is
|
||||
enabled if there is an `rr-cache` directory under the
|
||||
`$GIT_DIR`, e.g. if "rerere" was previously used in the
|
||||
repository.
|
||||
|
||||
sendemail.identity::
|
||||
A configuration identity. When given, causes values in the
|
||||
@ -1863,11 +1824,6 @@ tar.umask::
|
||||
archiving user's umask will be used instead. See umask(2) and
|
||||
linkgit:git-archive[1].
|
||||
|
||||
transfer.fsckObjects::
|
||||
When `fetch.fsckObjects` or `receive.fsckObjects` are
|
||||
not set, the value of this variable is used instead.
|
||||
Defaults to false.
|
||||
|
||||
transfer.unpackLimit::
|
||||
When `fetch.unpackLimit` or `receive.unpackLimit` are
|
||||
not set, the value of this variable is used instead.
|
||||
|
@ -45,24 +45,14 @@ ifndef::git-format-patch[]
|
||||
Synonym for `-p --raw`.
|
||||
endif::git-format-patch[]
|
||||
|
||||
--minimal::
|
||||
Spend extra time to make sure the smallest possible
|
||||
diff is produced.
|
||||
|
||||
--patience::
|
||||
Generate a diff using the "patience diff" algorithm.
|
||||
|
||||
--stat[=<width>[,<name-width>[,<count>]]]::
|
||||
--stat[=<width>[,<name-width>]]::
|
||||
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
|
||||
@ -408,10 +398,6 @@ endif::git-format-patch[]
|
||||
Show the context between diff hunks, up to the specified number
|
||||
of lines, thereby fusing hunks that are close to each other.
|
||||
|
||||
-W::
|
||||
--function-context::
|
||||
Show whole surrounding functions of changes.
|
||||
|
||||
ifndef::git-format-patch[]
|
||||
--exit-code::
|
||||
Make the program exit with codes similar to diff(1).
|
||||
|
@ -13,8 +13,7 @@ SYNOPSIS
|
||||
[--3way] [--interactive] [--committer-date-is-author-date]
|
||||
[--ignore-date] [--ignore-space-change | --ignore-whitespace]
|
||||
[--whitespace=<option>] [-C<n>] [-p<n>] [--directory=<dir>]
|
||||
[--exclude=<path>] [--reject] [-q | --quiet]
|
||||
[--scissors | --no-scissors]
|
||||
[--reject] [-q | --quiet] [--scissors | --no-scissors]
|
||||
[(<mbox> | <Maildir>)...]
|
||||
'git am' (--continue | --skip | --abort)
|
||||
|
||||
@ -88,7 +87,6 @@ default. You can use `--no-utf8` to override this.
|
||||
-C<n>::
|
||||
-p<n>::
|
||||
--directory=<dir>::
|
||||
--exclude=<path>::
|
||||
--reject::
|
||||
These flags are passed to the 'git apply' (see linkgit:git-apply[1])
|
||||
program that applies
|
||||
|
@ -101,25 +101,6 @@ tar.umask::
|
||||
details. If `--remote` is used then only the configuration of
|
||||
the remote repository takes effect.
|
||||
|
||||
tar.<format>.command::
|
||||
This variable specifies a shell command through which the tar
|
||||
output generated by `git archive` should be piped. The command
|
||||
is executed using the shell with the generated tar file on its
|
||||
standard input, and should produce the final output on its
|
||||
standard output. Any compression-level options will be passed
|
||||
to the command (e.g., "-9"). An output file with the same
|
||||
extension as `<format>` will be use this format if no other
|
||||
format is given.
|
||||
+
|
||||
The "tar.gz" and "tgz" formats are defined automatically and default to
|
||||
`gzip -cn`. You may override them with custom commands.
|
||||
|
||||
tar.<format>.remote::
|
||||
If true, enable `<format>` for use by remote clients via
|
||||
linkgit:git-upload-archive[1]. Defaults to false for
|
||||
user-defined formats, but true for the "tar.gz" and "tgz"
|
||||
formats.
|
||||
|
||||
ATTRIBUTES
|
||||
----------
|
||||
|
||||
@ -142,46 +123,32 @@ while archiving any tree in your `$GIT_DIR/info/attributes` file.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
`git archive --format=tar --prefix=junk/ HEAD | (cd /var/tmp/ && tar xf -)`::
|
||||
git archive --format=tar --prefix=junk/ HEAD | (cd /var/tmp/ && tar xf -)::
|
||||
|
||||
Create a tar archive that contains the contents of the
|
||||
latest commit on the current branch, and extract it in the
|
||||
`/var/tmp/junk` directory.
|
||||
|
||||
`git archive --format=tar --prefix=git-1.4.0/ v1.4.0 | gzip >git-1.4.0.tar.gz`::
|
||||
git archive --format=tar --prefix=git-1.4.0/ v1.4.0 | gzip >git-1.4.0.tar.gz::
|
||||
|
||||
Create a compressed tarball for v1.4.0 release.
|
||||
|
||||
`git archive --format=tar.gz --prefix=git-1.4.0/ v1.4.0 >git-1.4.0.tar.gz`::
|
||||
|
||||
Same as above, but using the builtin tar.gz handling.
|
||||
|
||||
`git archive --prefix=git-1.4.0/ -o git-1.4.0.tar.gz v1.4.0`::
|
||||
|
||||
Same as above, but the format is inferred from the output file.
|
||||
|
||||
`git archive --format=tar --prefix=git-1.4.0/ v1.4.0{caret}\{tree\} | gzip >git-1.4.0.tar.gz`::
|
||||
git archive --format=tar --prefix=git-1.4.0/ v1.4.0{caret}\{tree\} | gzip >git-1.4.0.tar.gz::
|
||||
|
||||
Create a compressed tarball for v1.4.0 release, but without a
|
||||
global extended pax header.
|
||||
|
||||
`git archive --format=zip --prefix=git-docs/ HEAD:Documentation/ > git-1.4.0-docs.zip`::
|
||||
git archive --format=zip --prefix=git-docs/ HEAD:Documentation/ > git-1.4.0-docs.zip::
|
||||
|
||||
Put everything in the current head's Documentation/ directory
|
||||
into 'git-1.4.0-docs.zip', with the prefix 'git-docs/'.
|
||||
|
||||
`git archive -o latest.zip HEAD`::
|
||||
git archive -o latest.zip HEAD::
|
||||
|
||||
Create a Zip archive that contains the contents of the latest
|
||||
commit on the current branch. Note that the output format is
|
||||
inferred by the extension of the output file.
|
||||
|
||||
`git config tar.tar.xz.command "xz -c"`::
|
||||
|
||||
Configure a "tar.xz" format for making LZMA-compressed tarfiles.
|
||||
You can use it specifying `--format=tar.xz`, or by creating an
|
||||
output file like `-o foo.tar.xz`.
|
||||
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
|
@ -17,7 +17,7 @@ The command takes various subcommands, and different options depending
|
||||
on the subcommand:
|
||||
|
||||
git bisect help
|
||||
git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<paths>...]
|
||||
git bisect start [<bad> [<good>...]] [--] [<paths>...]
|
||||
git bisect bad [<rev>]
|
||||
git bisect good [<rev>...]
|
||||
git bisect skip [(<rev>|<range>)...]
|
||||
@ -263,19 +263,6 @@ rewind the tree to the pristine state. Finally the script should exit
|
||||
with the status of the real test to let the "git bisect run" command loop
|
||||
determine the eventual outcome of the bisect session.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
--no-checkout::
|
||||
+
|
||||
Do not checkout the new working tree at each iteration of the bisection
|
||||
process. Instead just update a special reference named 'BISECT_HEAD' to make
|
||||
it point to the commit that should be tested.
|
||||
+
|
||||
This option may be useful when the test you would perform in each step
|
||||
does not require a checked out tree.
|
||||
+
|
||||
If the repository is bare, `--no-checkout` is assumed.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
|
||||
@ -356,25 +343,6 @@ $ git bisect run sh -c "make || exit 125; ~/check_test_case.sh"
|
||||
This shows that you can do without a run script if you write the test
|
||||
on a single line.
|
||||
|
||||
* Locate a good region of the object graph in a damaged repository
|
||||
+
|
||||
------------
|
||||
$ git bisect start HEAD <known-good-commit> [ <boundary-commit> ... ] --no-checkout
|
||||
$ git bisect run sh -c '
|
||||
GOOD=$(git for-each-ref "--format=%(objectname)" refs/bisect/good-*) &&
|
||||
git rev-list --objects BISECT_HEAD --not $GOOD >tmp.$$ &&
|
||||
git pack-objects --stdout >/dev/null <tmp.$$
|
||||
rc=$?
|
||||
rm -f tmp.$$
|
||||
test $rc = 0'
|
||||
|
||||
------------
|
||||
+
|
||||
In this case, when 'git bisect run' finishes, bisect/bad will refer to a commit that
|
||||
has at least one parent whose reachable graph is fully traversable in the sense
|
||||
required by 'git pack objects'.
|
||||
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
link:git-bisect-lk2009.html[Fighting regressions with git bisect],
|
||||
|
@ -9,8 +9,8 @@ SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git branch' [--color[=<when>] | --no-color] [-r | -a]
|
||||
[--list] [-v [--abbrev=<length> | --no-abbrev]]
|
||||
[(--merged | --no-merged | --contains) [<commit>]] [<pattern>...]
|
||||
[-v [--abbrev=<length> | --no-abbrev]]
|
||||
[(--merged | --no-merged | --contains) [<commit>]]
|
||||
'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]
|
||||
'git branch' (-m | -M) [<oldbranch>] <newbranch>
|
||||
'git branch' (-d | -D) [-r] <branchname>...
|
||||
@ -20,11 +20,7 @@ DESCRIPTION
|
||||
|
||||
With no arguments, existing branches are listed and the current branch will
|
||||
be highlighted with an asterisk. Option `-r` causes the remote-tracking
|
||||
branches to be listed, and option `-a` shows both. This list mode is also
|
||||
activated by the `--list` option (see below).
|
||||
<pattern> restricts the output to matching branches, the pattern is a shell
|
||||
wildcard (i.e., matched using fnmatch(3))
|
||||
Multiple patterns may be given; if any of them matches, the tag is shown.
|
||||
branches to be listed, and option `-a` shows both.
|
||||
|
||||
With `--contains`, shows only the branches that contain the named commit
|
||||
(in other words, the branches whose tip commits are descendants of the
|
||||
@ -68,7 +64,6 @@ way to clean up all obsolete remote-tracking branches.
|
||||
OPTIONS
|
||||
-------
|
||||
-d::
|
||||
--delete::
|
||||
Delete a branch. The branch must be fully merged in its
|
||||
upstream branch, or in `HEAD` if no upstream was set with
|
||||
`--track` or `--set-upstream`.
|
||||
@ -77,7 +72,6 @@ OPTIONS
|
||||
Delete a branch irrespective of its merged status.
|
||||
|
||||
-l::
|
||||
--create-reflog::
|
||||
Create the branch's reflog. This activates recording of
|
||||
all changes made to the branch ref, enabling use of date
|
||||
based sha1 expressions such as "<branchname>@\{yesterday}".
|
||||
@ -90,7 +84,6 @@ OPTIONS
|
||||
already. Without `-f` 'git branch' refuses to change an existing branch.
|
||||
|
||||
-m::
|
||||
--move::
|
||||
Move/rename a branch and the corresponding reflog.
|
||||
|
||||
-M::
|
||||
@ -107,28 +100,20 @@ OPTIONS
|
||||
Same as `--color=never`.
|
||||
|
||||
-r::
|
||||
--remotes::
|
||||
List or delete (if used with -d) the remote-tracking branches.
|
||||
|
||||
-a::
|
||||
--all::
|
||||
List both remote-tracking branches and local branches.
|
||||
|
||||
--list::
|
||||
Activate the list mode. `git branch <pattern>` would try to create a branch,
|
||||
use `git branch --list <pattern>` to list matching branches.
|
||||
|
||||
-v::
|
||||
--verbose::
|
||||
When in list mode,
|
||||
show sha1 and commit subject line for each head, along with
|
||||
Show sha1 and commit subject line for each head, along with
|
||||
relationship to upstream branch (if any). If given twice, print
|
||||
the name of the upstream branch, as well.
|
||||
|
||||
--abbrev=<length>::
|
||||
Alter the sha1's minimum display length in the output listing.
|
||||
The default value is 7 and can be overridden by the `core.abbrev`
|
||||
config option.
|
||||
The default value is 7.
|
||||
|
||||
--no-abbrev::
|
||||
Display the full sha1s in the output listing rather than abbreviating them.
|
||||
|
@ -9,8 +9,8 @@ git-check-attr - Display gitattributes information
|
||||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git check-attr' [-a | --all | attr...] [--] pathname...
|
||||
'git check-attr' --stdin [-z] [-a | --all | attr...] < <list-of-paths>
|
||||
'git check-attr' attr... [--] pathname...
|
||||
'git check-attr' --stdin [-z] attr... < <list-of-paths>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@ -19,14 +19,6 @@ For every pathname, this command will list if each attribute is 'unspecified',
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
-a, --all::
|
||||
List all attributes that are associated with the specified
|
||||
paths. If this option is used, then 'unspecified' attributes
|
||||
will not be included in the output.
|
||||
|
||||
--cached::
|
||||
Consider `.gitattributes` in the index only, ignoring the working tree.
|
||||
|
||||
--stdin::
|
||||
Read file names from stdin instead of from the command-line.
|
||||
|
||||
@ -36,11 +28,8 @@ OPTIONS
|
||||
|
||||
\--::
|
||||
Interpret all preceding arguments as attributes and all following
|
||||
arguments as path names.
|
||||
|
||||
If none of `--stdin`, `--all`, or `--` is used, the first argument
|
||||
will be treated as an attribute and the rest of the arguments as
|
||||
pathnames.
|
||||
arguments as path names. If not supplied, only the first argument will
|
||||
be treated as an attribute.
|
||||
|
||||
OUTPUT
|
||||
------
|
||||
@ -80,13 +69,6 @@ org/example/MyClass.java: diff: java
|
||||
org/example/MyClass.java: myAttr: set
|
||||
---------------
|
||||
|
||||
* Listing all attributes for a file:
|
||||
---------------
|
||||
$ git check-attr --all -- org/example/MyClass.java
|
||||
org/example/MyClass.java: diff: java
|
||||
org/example/MyClass.java: myAttr: set
|
||||
---------------
|
||||
|
||||
* Listing an attribute for multiple files:
|
||||
---------------
|
||||
$ git check-attr myAttr -- org/example/MyClass.java org/example/NoMyAttr.java
|
||||
|
@ -8,9 +8,8 @@ git-check-ref-format - Ensures that a reference name is well formed
|
||||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git check-ref-format' [--normalize]
|
||||
[--[no-]allow-onelevel] [--refspec-pattern]
|
||||
<refname>
|
||||
'git check-ref-format' <refname>
|
||||
'git check-ref-format' --print <refname>
|
||||
'git check-ref-format' --branch <branchname-shorthand>
|
||||
|
||||
DESCRIPTION
|
||||
@ -29,28 +28,22 @@ git imposes the following rules on how references are named:
|
||||
|
||||
. They can include slash `/` for hierarchical (directory)
|
||||
grouping, but no slash-separated component can begin with a
|
||||
dot `.` or end with the sequence `.lock`.
|
||||
dot `.`.
|
||||
|
||||
. They must contain at least one `/`. This enforces the presence of a
|
||||
category like `heads/`, `tags/` etc. but the actual names are not
|
||||
restricted. If the `--allow-onelevel` option is used, this rule
|
||||
is waived.
|
||||
restricted.
|
||||
|
||||
. They cannot have two consecutive dots `..` anywhere.
|
||||
|
||||
. They cannot have ASCII control characters (i.e. bytes whose
|
||||
values are lower than \040, or \177 `DEL`), space, tilde `~`,
|
||||
caret `{caret}`, or colon `:` anywhere.
|
||||
caret `{caret}`, colon `:`, question-mark `?`, asterisk `*`,
|
||||
or open bracket `[` anywhere.
|
||||
|
||||
. They cannot have question-mark `?`, asterisk `{asterisk}`, or open
|
||||
bracket `[` anywhere. See the `--refspec-pattern` option below for
|
||||
an exception to this rule.
|
||||
. They cannot end with a slash `/` nor a dot `.`.
|
||||
|
||||
. They cannot begin or end with a slash `/` or contain multiple
|
||||
consecutive slashes (see the `--normalize` option below for an
|
||||
exception to this rule)
|
||||
|
||||
. They cannot end with a dot `.`.
|
||||
. They cannot end with the sequence `.lock`.
|
||||
|
||||
. They cannot contain a sequence `@{`.
|
||||
|
||||
@ -75,36 +68,16 @@ reference name expressions (see linkgit:gitrevisions[7]):
|
||||
|
||||
. at-open-brace `@{` is used as a notation to access a reflog entry.
|
||||
|
||||
With the `--print` option, if 'refname' is acceptable, it prints the
|
||||
canonicalized name of a hypothetical reference with that name. That is,
|
||||
it prints 'refname' with any extra `/` characters removed.
|
||||
|
||||
With the `--branch` option, it expands the ``previous branch syntax''
|
||||
`@{-n}`. For example, `@{-1}` is a way to refer the last branch you
|
||||
were on. This option should be used by porcelains to accept this
|
||||
syntax anywhere a branch name is expected, so they can act as if you
|
||||
typed the branch name.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
--allow-onelevel::
|
||||
--no-allow-onelevel::
|
||||
Controls whether one-level refnames are accepted (i.e.,
|
||||
refnames that do not contain multiple `/`-separated
|
||||
components). The default is `--no-allow-onelevel`.
|
||||
|
||||
--refspec-pattern::
|
||||
Interpret <refname> as a reference name pattern for a refspec
|
||||
(as used with remote repositories). If this option is
|
||||
enabled, <refname> is allowed to contain a single `{asterisk}`
|
||||
in place of a one full pathname component (e.g.,
|
||||
`foo/{asterisk}/bar` but not `foo/bar{asterisk}`).
|
||||
|
||||
--normalize::
|
||||
Normalize 'refname' by removing any leading slash (`/`)
|
||||
characters and collapsing runs of adjacent slashes between
|
||||
name components into a single slash. Iff the normalized
|
||||
refname is valid then print it to standard output and exit
|
||||
with a status of 0. (`--print` is a deprecated way to spell
|
||||
`--normalize`.)
|
||||
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
|
||||
@ -117,7 +90,7 @@ $ git check-ref-format --branch @{-1}
|
||||
* Determine the reference name to use for a new branch:
|
||||
+
|
||||
------------
|
||||
$ ref=$(git check-ref-format --normalize "refs/heads/$newbranch") ||
|
||||
$ ref=$(git check-ref-format --print "refs/heads/$newbranch") ||
|
||||
die "we do not like '$newbranch' as a branch name."
|
||||
------------
|
||||
|
||||
|
@ -9,8 +9,6 @@ SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git cherry-pick' [--edit] [-n] [-m parent-number] [-s] [-x] [--ff] <commit>...
|
||||
'git cherry-pick' --reset
|
||||
'git cherry-pick' --continue
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@ -112,37 +110,33 @@ effect to your index in a row.
|
||||
Pass the merge strategy-specific option through to the
|
||||
merge strategy. See linkgit:git-merge[1] for details.
|
||||
|
||||
SEQUENCER SUBCOMMANDS
|
||||
---------------------
|
||||
include::sequencer.txt[]
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
`git cherry-pick master`::
|
||||
git cherry-pick master::
|
||||
|
||||
Apply the change introduced by the commit at the tip of the
|
||||
master branch and create a new commit with this change.
|
||||
|
||||
`git cherry-pick ..master`::
|
||||
`git cherry-pick ^HEAD master`::
|
||||
git cherry-pick ..master::
|
||||
git cherry-pick ^HEAD master::
|
||||
|
||||
Apply the changes introduced by all commits that are ancestors
|
||||
of master but not of HEAD to produce new commits.
|
||||
|
||||
`git cherry-pick master{tilde}4 master{tilde}2`::
|
||||
git cherry-pick master{tilde}4 master{tilde}2::
|
||||
|
||||
Apply the changes introduced by the fifth and third last
|
||||
commits pointed to by master and create 2 new commits with
|
||||
these changes.
|
||||
|
||||
`git cherry-pick -n master~1 next`::
|
||||
git cherry-pick -n master~1 next::
|
||||
|
||||
Apply to the working tree and the index the changes introduced
|
||||
by the second last commit pointed to by master and by the last
|
||||
commit pointed to by next, but do not create any commit with
|
||||
these changes.
|
||||
|
||||
`git cherry-pick --ff ..next`::
|
||||
git cherry-pick --ff ..next::
|
||||
|
||||
If history is linear and HEAD is an ancestor of next, update
|
||||
the working tree and advance the HEAD pointer to match next.
|
||||
@ -150,7 +144,7 @@ EXAMPLES
|
||||
are in next but not HEAD to the current branch, creating a new
|
||||
commit for each new change.
|
||||
|
||||
`git rev-list --reverse master \-- README | git cherry-pick -n --stdin`::
|
||||
git rev-list --reverse master \-- README | git cherry-pick -n --stdin::
|
||||
|
||||
Apply the changes introduced by all commits on the master
|
||||
branch that touched README to the working tree and index,
|
||||
|
@ -47,14 +47,12 @@ OPTIONS
|
||||
|
||||
-e <pattern>::
|
||||
--exclude=<pattern>::
|
||||
In addition to those found in .gitignore (per directory) and
|
||||
$GIT_DIR/info/exclude, also consider these patterns to be in the
|
||||
set of the ignore rules in effect.
|
||||
Specify special exceptions to not be cleaned. Each <pattern> is
|
||||
the same form as in $GIT_DIR/info/excludes and this option can be
|
||||
given multiple times.
|
||||
|
||||
-x::
|
||||
Don't use the standard ignore rules read from .gitignore (per
|
||||
directory) and $GIT_DIR/info/exclude, but do still use the ignore
|
||||
rules given with `-e` options. This allows removing all untracked
|
||||
Don't use the ignore rules. This allows removing all untracked
|
||||
files, including build products. This can be used (possibly in
|
||||
conjunction with 'git reset') to create a pristine
|
||||
working directory to test a clean build.
|
||||
|
@ -159,17 +159,6 @@ objects from the source repository into a pack in the cloned repository.
|
||||
Specify the directory from which templates will be used;
|
||||
(See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
|
||||
|
||||
--config <key>=<value>::
|
||||
-c <key>=<value>::
|
||||
Set a configuration variable in the newly-created repository;
|
||||
this takes effect immediately after the repository is
|
||||
initialized, but before the remote history is fetched or any
|
||||
files checked out. The key is in the same format as expected by
|
||||
linkgit:git-config[1] (e.g., `core.eol=true`). If multiple
|
||||
values are given for the same key, each value will be written to
|
||||
the config file. This makes it safe, for example, to add
|
||||
additional fetch refspecs to the origin remote.
|
||||
|
||||
--depth <depth>::
|
||||
Create a 'shallow' clone with a history truncated to the
|
||||
specified number of revisions. A shallow repository has a
|
||||
|
@ -68,9 +68,7 @@ if set:
|
||||
|
||||
In case (some of) these environment variables are not set, the information
|
||||
is taken from the configuration items user.name and user.email, or, if not
|
||||
present, system user name and the hostname used for outgoing mail (taken
|
||||
from `/etc/mailname` and falling back to the fully qualified hostname when
|
||||
that file does not exist).
|
||||
present, system user name and fully qualified hostname.
|
||||
|
||||
A commit comment is read from stdin. If a changelog
|
||||
entry is not provided via "<" redirection, 'git commit-tree' will just wait
|
||||
@ -92,10 +90,6 @@ Discussion
|
||||
|
||||
include::i18n.txt[]
|
||||
|
||||
FILES
|
||||
-----
|
||||
/etc/mailname
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
linkgit:git-write-tree[1]
|
||||
|
@ -93,14 +93,14 @@ OPTIONS
|
||||
Listen on an alternative port. Incompatible with '--inetd' option.
|
||||
|
||||
--init-timeout=<n>::
|
||||
Timeout (in seconds) between the moment the connection is established
|
||||
and the client request is received (typically a rather low value, since
|
||||
Timeout between the moment the connection is established and the
|
||||
client request is received (typically a rather low value, since
|
||||
that should be basically immediate).
|
||||
|
||||
--timeout=<n>::
|
||||
Timeout (in seconds) for specific client sub-requests. This includes
|
||||
the time it takes for the server to process the sub-request and the
|
||||
time spent waiting for the next client's request.
|
||||
Timeout for specific client sub-requests. This includes the time
|
||||
it takes for the server to process the sub-request and the time spent
|
||||
waiting for the next client's request.
|
||||
|
||||
--max-connections=<n>::
|
||||
Maximum number of concurrent clients, defaults to 32. Set it to
|
||||
@ -161,16 +161,6 @@ the facility of inet daemon to achieve the same before spawning
|
||||
repository configuration. By default, all the services
|
||||
are overridable.
|
||||
|
||||
--informative-errors::
|
||||
--no-informative-errors::
|
||||
When informative errors are turned on, git-daemon will report
|
||||
more verbose errors to the client, differentiating conditions
|
||||
like "no such repository" from "repository not exported". This
|
||||
is more convenient for clients, but may leak information about
|
||||
the existence of unexported repositories. When informative
|
||||
errors are not enabled, all errors report "access denied" to the
|
||||
client. The default is --no-informative-errors.
|
||||
|
||||
<directory>::
|
||||
A directory to add to the whitelist of allowed directories. Unless
|
||||
--strict-paths is specified this will also include subdirectories
|
||||
|
@ -83,10 +83,6 @@ marks the same across runs.
|
||||
allow that. So fake a tagger to be able to fast-import the
|
||||
output.
|
||||
|
||||
--use-done-feature::
|
||||
Start the stream with a 'feature done' stanza, and terminate
|
||||
it with a 'done' command.
|
||||
|
||||
--no-data::
|
||||
Skip output of blob objects and instead refer to blobs via
|
||||
their original SHA-1 hash. This is useful when rewriting the
|
||||
|
@ -102,12 +102,6 @@ OPTIONS
|
||||
when the `cat-blob` command is encountered in the stream.
|
||||
The default behaviour is to write to `stdout`.
|
||||
|
||||
--done::
|
||||
Require a `done` command at the end of the stream.
|
||||
This option might be useful for detecting errors that
|
||||
cause the frontend to terminate before it has started to
|
||||
write a stream.
|
||||
|
||||
--export-pack-edges=<file>::
|
||||
After creating a packfile, print a line of data to
|
||||
<file> listing the filename of the packfile and the last
|
||||
@ -337,11 +331,6 @@ and control the current import process. More detailed discussion
|
||||
standard output. This command is optional and is not needed
|
||||
to perform an import.
|
||||
|
||||
`done`::
|
||||
Marks the end of the stream. This command is optional
|
||||
unless the `done` feature was requested using the
|
||||
`--done` command line option or `feature done` command.
|
||||
|
||||
`cat-blob`::
|
||||
Causes fast-import to print a blob in 'cat-file --batch'
|
||||
format to the file descriptor set with `--cat-blob-fd` or
|
||||
@ -425,8 +414,8 @@ Here `<name>` is the person's display name (for example
|
||||
(``cm@example.com''). `LT` and `GT` are the literal less-than (\x3c)
|
||||
and greater-than (\x3e) symbols. These are required to delimit
|
||||
the email address from the other fields in the line. Note that
|
||||
`<name>` and `<email>` are free-form and may contain any sequence
|
||||
of bytes, except `LT`, `GT` and `LF`. `<name>` is typically UTF-8 encoded.
|
||||
`<name>` is free-form and may contain any sequence of bytes, except
|
||||
`LT` and `LF`. It is typically UTF-8 encoded.
|
||||
|
||||
The time of the change is specified by `<when>` using the date format
|
||||
that was selected by the \--date-format=<fmt> command line option.
|
||||
@ -1012,14 +1001,10 @@ force::
|
||||
(see OPTIONS, above).
|
||||
|
||||
import-marks::
|
||||
import-marks-if-exists::
|
||||
Like --import-marks except in two respects: first, only one
|
||||
"feature import-marks" or "feature import-marks-if-exists"
|
||||
command is allowed per stream; second, an --import-marks=
|
||||
or --import-marks-if-exists command-line option overrides
|
||||
any of these "feature" commands in the stream; third,
|
||||
"feature import-marks-if-exists" like a corresponding
|
||||
command-line option silently skips a nonexistent file.
|
||||
"feature import-marks" command is allowed per stream;
|
||||
second, an --import-marks= command-line option overrides
|
||||
any "feature import-marks" command in the stream.
|
||||
|
||||
cat-blob::
|
||||
ls::
|
||||
@ -1036,11 +1021,6 @@ notes::
|
||||
Versions of fast-import not supporting notes will exit
|
||||
with a message indicating so.
|
||||
|
||||
done::
|
||||
Error out if the stream ends without a 'done' command.
|
||||
Without this feature, errors causing the frontend to end
|
||||
abruptly at a convenient point in the stream can go
|
||||
undetected.
|
||||
|
||||
`option`
|
||||
~~~~~~~~
|
||||
@ -1070,15 +1050,6 @@ not be passed as option:
|
||||
* cat-blob-fd
|
||||
* force
|
||||
|
||||
`done`
|
||||
~~~~~~
|
||||
If the `done` feature is not in use, treated as if EOF was read.
|
||||
This can be used to tell fast-import to finish early.
|
||||
|
||||
If the `--done` command line option or `feature done` command is
|
||||
in use, the `done` command is mandatory and marks the end of the
|
||||
stream.
|
||||
|
||||
Crash Reports
|
||||
-------------
|
||||
If fast-import is supplied invalid input it will terminate with a
|
||||
|
@ -101,10 +101,9 @@ Fields that have name-email-date tuple as its value (`author`,
|
||||
`committer`, and `tagger`) can be suffixed with `name`, `email`,
|
||||
and `date` to extract the named component.
|
||||
|
||||
The complete message in a commit and tag object is `contents`.
|
||||
Its first line is `contents:subject`, the remaining lines
|
||||
are `contents:body` and the optional GPG signature
|
||||
is `contents:signature`.
|
||||
The first line of the message in a commit and tag object is
|
||||
`subject`, the remaining lines are `body`. The whole message
|
||||
is `contents`.
|
||||
|
||||
For sorting purposes, fields with numeric values sort in numeric
|
||||
order (`objectsize`, `authordate`, `committerdate`, `taggerdate`).
|
||||
|
@ -166,22 +166,15 @@ will want to ensure that threading is disabled for `git send-email`.
|
||||
--to=<email>::
|
||||
Add a `To:` header to the email headers. This is in addition
|
||||
to any configured headers, and may be used multiple times.
|
||||
The negated form `--no-to` discards all `To:` headers added so
|
||||
far (from config or command line).
|
||||
|
||||
--cc=<email>::
|
||||
Add a `Cc:` header to the email headers. This is in addition
|
||||
to any configured headers, and may be used multiple times.
|
||||
The negated form `--no-cc` discards all `Cc:` headers added so
|
||||
far (from config or command line).
|
||||
|
||||
--add-header=<header>::
|
||||
Add an arbitrary header to the email headers. This is in addition
|
||||
to any configured headers, and may be used multiple times.
|
||||
For example, `--add-header="Organization: git-foo"`.
|
||||
The negated form `--no-add-header` discards *all* (`To:`,
|
||||
`Cc:`, and custom) headers added so far from config or command
|
||||
line.
|
||||
For example, `--add-header="Organization: git-foo"`
|
||||
|
||||
--cover-letter::
|
||||
In addition to the patches, generate a cover letter file
|
||||
|
@ -23,7 +23,7 @@ SYNOPSIS
|
||||
[-A <post-context>] [-B <pre-context>] [-C <context>]
|
||||
[-f <file>] [-e] <pattern>
|
||||
[--and|--or|--not|(|)|-e <pattern>...]
|
||||
[ [--exclude-standard] [--cached | --no-index | --untracked] | <tree>...]
|
||||
[--cached | --no-index | <tree>...]
|
||||
[--] [<pathspec>...]
|
||||
|
||||
DESCRIPTION
|
||||
@ -49,20 +49,7 @@ OPTIONS
|
||||
blobs registered in the index file.
|
||||
|
||||
--no-index::
|
||||
Search files in the current directory that is not managed by git.
|
||||
|
||||
--untracked::
|
||||
In addition to searching in the tracked files in the working
|
||||
tree, search also in untracked files.
|
||||
|
||||
--no-exclude-standard::
|
||||
Also search in ignored files by not honoring the `.gitignore`
|
||||
mechanism. Only useful with `--untracked`.
|
||||
|
||||
--exclude-standard::
|
||||
Do not pay attention to ignored files specified via the `.gitignore`
|
||||
mechanism. Only useful when searching files in the current directory
|
||||
with `--no-index`.
|
||||
Search files in the current directory, not just those tracked by git.
|
||||
|
||||
-a::
|
||||
--text::
|
||||
@ -161,12 +148,14 @@ OPTIONS
|
||||
gives the default to color output.
|
||||
Same as `--color=never`.
|
||||
|
||||
--break::
|
||||
Print an empty line between matches from different files.
|
||||
-[ABC] <context>::
|
||||
Show `context` trailing (`A` -- after), or leading (`B`
|
||||
-- before), or both (`C` -- context) lines, and place a
|
||||
line containing `--` between contiguous groups of
|
||||
matches.
|
||||
|
||||
--heading::
|
||||
Show the filename above the matches in that file instead of
|
||||
at the start of each shown line.
|
||||
-<num>::
|
||||
A shortcut for specifying `-C<num>`.
|
||||
|
||||
-p::
|
||||
--show-function::
|
||||
@ -176,29 +165,6 @@ OPTIONS
|
||||
patch hunk headers (see 'Defining a custom hunk-header' in
|
||||
linkgit:gitattributes[5]).
|
||||
|
||||
-<num>::
|
||||
-C <num>::
|
||||
--context <num>::
|
||||
Show <num> leading and trailing lines, and place a line
|
||||
containing `--` between contiguous groups of matches.
|
||||
|
||||
-A <num>::
|
||||
--after-context <num>::
|
||||
Show <num> trailing lines, and place a line containing
|
||||
`--` between contiguous groups of matches.
|
||||
|
||||
-B <num>::
|
||||
--before-context <num>::
|
||||
Show <num> leading lines, and place a line containing
|
||||
`--` between contiguous groups of matches.
|
||||
|
||||
-W::
|
||||
--function-context::
|
||||
Show the surrounding text from the previous line containing a
|
||||
function name up to the one before the next function name,
|
||||
effectively showing the whole function in which the match was
|
||||
found.
|
||||
|
||||
-f <file>::
|
||||
Read patterns from <file>, one per line.
|
||||
|
||||
@ -242,15 +208,15 @@ OPTIONS
|
||||
Examples
|
||||
--------
|
||||
|
||||
`git grep {apostrophe}time_t{apostrophe} \-- {apostrophe}*.[ch]{apostrophe}`::
|
||||
git grep {apostrophe}time_t{apostrophe} \-- {apostrophe}*.[ch]{apostrophe}::
|
||||
Looks for `time_t` in all tracked .c and .h files in the working
|
||||
directory and its subdirectories.
|
||||
|
||||
`git grep -e {apostrophe}#define{apostrophe} --and \( -e MAX_PATH -e PATH_MAX \)`::
|
||||
git grep -e {apostrophe}#define{apostrophe} --and \( -e MAX_PATH -e PATH_MAX \)::
|
||||
Looks for a line that has `#define` and either `MAX_PATH` or
|
||||
`PATH_MAX`.
|
||||
|
||||
`git grep --all-match -e NODE -e Unexpected`::
|
||||
git grep --all-match -e NODE -e Unexpected::
|
||||
Looks for a line that has `NODE` or `Unexpected` in
|
||||
files that have lines that match both.
|
||||
|
||||
|
@ -50,7 +50,7 @@ version::
|
||||
|
||||
Examples
|
||||
--------
|
||||
`git gui blame Makefile`::
|
||||
git gui blame Makefile::
|
||||
|
||||
Show the contents of the file 'Makefile' in the current
|
||||
working directory, and provide annotations for both the
|
||||
@ -59,41 +59,41 @@ Examples
|
||||
uncommitted changes (if any) are explicitly attributed to
|
||||
'Not Yet Committed'.
|
||||
|
||||
`git gui blame v0.99.8 Makefile`::
|
||||
git gui blame v0.99.8 Makefile::
|
||||
|
||||
Show the contents of 'Makefile' in revision 'v0.99.8'
|
||||
and provide annotations for each line. Unlike the above
|
||||
example the file is read from the object database and not
|
||||
the working directory.
|
||||
|
||||
`git gui blame --line=100 Makefile`::
|
||||
git gui blame --line=100 Makefile::
|
||||
|
||||
Loads annotations as described above and automatically
|
||||
scrolls the view to center on line '100'.
|
||||
|
||||
`git gui citool`::
|
||||
git gui citool::
|
||||
|
||||
Make one commit and return to the shell when it is complete.
|
||||
This command returns a non-zero exit code if the window was
|
||||
closed in any way other than by making a commit.
|
||||
|
||||
`git gui citool --amend`::
|
||||
git gui citool --amend::
|
||||
|
||||
Automatically enter the 'Amend Last Commit' mode of
|
||||
the interface.
|
||||
|
||||
`git gui citool --nocommit`::
|
||||
git gui citool --nocommit::
|
||||
|
||||
Behave as normal citool, but instead of making a commit
|
||||
simply terminate with a zero exit code. It still checks
|
||||
that the index does not contain any unmerged entries, so
|
||||
you can use it as a GUI version of linkgit:git-mergetool[1]
|
||||
|
||||
`git citool`::
|
||||
git citool::
|
||||
|
||||
Same as `git gui citool` (above).
|
||||
|
||||
`git gui browser maint`::
|
||||
git gui browser maint::
|
||||
|
||||
Show a browser for the tree of the 'maint' branch. Files
|
||||
selected in the browser can be viewed with the internal
|
||||
|
@ -119,14 +119,6 @@ ScriptAliasMatch \
|
||||
|
||||
ScriptAlias /git/ /var/www/cgi-bin/gitweb.cgi/
|
||||
----------------------------------------------------------------
|
||||
+
|
||||
To serve multiple repositories from different linkgit:gitnamespaces[7] in a
|
||||
single repository:
|
||||
+
|
||||
----------------------------------------------------------------
|
||||
SetEnvIf Request_URI "^/git/([^/]*)" GIT_NAMESPACE=$1
|
||||
ScriptAliasMatch ^/git/[^/]*(.*) /usr/libexec/git-core/git-http-backend/storage.git$1
|
||||
----------------------------------------------------------------
|
||||
|
||||
Accelerated static Apache 2.x::
|
||||
Similar to the above, but Apache can be used to return static
|
||||
|
@ -15,9 +15,6 @@ DESCRIPTION
|
||||
-----------
|
||||
Downloads a remote git repository via HTTP.
|
||||
|
||||
*NOTE*: use of this command without -a is deprecated. The -a
|
||||
behaviour will become the default in a future release.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
commit-id::
|
||||
|
@ -51,8 +51,8 @@ OPTIONS
|
||||
|
||||
start::
|
||||
--start::
|
||||
Start the httpd instance and exit. Regenerate configuration files
|
||||
as necessary for spawning a new instance.
|
||||
Start the httpd instance and exit. This does not generate
|
||||
any of the configuration files for spawning a new instance.
|
||||
|
||||
stop::
|
||||
--stop::
|
||||
@ -62,8 +62,8 @@ stop::
|
||||
|
||||
restart::
|
||||
--restart::
|
||||
Restart the httpd instance and exit. Regenerate configuration files
|
||||
as necessary for spawning a new instance.
|
||||
Restart the httpd instance and exit. This does not generate
|
||||
any of the configuration files for spawning a new instance.
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
@ -84,10 +84,6 @@ If the configuration variable 'instaweb.browser' is not set,
|
||||
'web.browser' will be used instead if it is defined. See
|
||||
linkgit:git-web{litdd}browse[1] for more information about this.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
linkgit:gitweb[1]
|
||||
|
||||
GIT
|
||||
---
|
||||
Part of the linkgit:git[1] suite
|
||||
|
@ -91,45 +91,45 @@ include::diff-generate-patch.txt[]
|
||||
|
||||
Examples
|
||||
--------
|
||||
`git log --no-merges`::
|
||||
git log --no-merges::
|
||||
|
||||
Show the whole commit history, but skip any merges
|
||||
|
||||
`git log v2.6.12.. include/scsi drivers/scsi`::
|
||||
git log v2.6.12.. include/scsi drivers/scsi::
|
||||
|
||||
Show all commits since version 'v2.6.12' that changed any file
|
||||
in the include/scsi or drivers/scsi subdirectories
|
||||
|
||||
`git log --since="2 weeks ago" \-- gitk`::
|
||||
git log --since="2 weeks ago" \-- gitk::
|
||||
|
||||
Show the changes during the last two weeks to the file 'gitk'.
|
||||
The "--" is necessary to avoid confusion with the *branch* named
|
||||
'gitk'
|
||||
|
||||
`git log --name-status release..test`::
|
||||
git log --name-status release..test::
|
||||
|
||||
Show the commits that are in the "test" branch but not yet
|
||||
in the "release" branch, along with the list of paths
|
||||
each commit modifies.
|
||||
|
||||
`git log --follow builtin-rev-list.c`::
|
||||
git log --follow builtin-rev-list.c::
|
||||
|
||||
Shows the commits that changed builtin-rev-list.c, including
|
||||
those commits that occurred before the file was given its
|
||||
present name.
|
||||
|
||||
`git log --branches --not --remotes=origin`::
|
||||
git log --branches --not --remotes=origin::
|
||||
|
||||
Shows all commits that are in any of local branches but not in
|
||||
any of remote-tracking branches for 'origin' (what you have that
|
||||
origin doesn't).
|
||||
|
||||
`git log master --not --remotes=*/master`::
|
||||
git log master --not --remotes=*/master::
|
||||
|
||||
Shows all commits that are in local master but not in any remote
|
||||
repository master branches.
|
||||
|
||||
`git log -p -m --first-parent`::
|
||||
git log -p -m --first-parent::
|
||||
|
||||
Shows the history including change diffs, but only from the
|
||||
"main branch" perspective, skipping commits that come from merged
|
||||
|
@ -76,12 +76,12 @@ OPTIONS
|
||||
EXAMPLES
|
||||
--------
|
||||
|
||||
`git merge-file README.my README README.upstream`::
|
||||
git merge-file README.my README README.upstream::
|
||||
|
||||
combines the changes of README.my and README.upstream since README,
|
||||
tries to merge them and writes the result into README.my.
|
||||
|
||||
`git merge-file -L a -L b -L c tmp/a123 tmp/b234 tmp/c345`::
|
||||
git merge-file -L a -L b -L c tmp/a123 tmp/b234 tmp/c345::
|
||||
|
||||
merges tmp/a123 and tmp/c345 with the base tmp/b234, but uses labels
|
||||
`a` and `c` instead of `tmp/a123` and `tmp/c345`.
|
||||
|
@ -142,9 +142,8 @@ OPTIONS
|
||||
|
||||
-C <object>::
|
||||
--reuse-message=<object>::
|
||||
Take the given blob object (for example, another note) as the
|
||||
note message. (Use `git notes copy <object>` instead to
|
||||
copy notes between objects.)
|
||||
Take the note message from the given blob object (for
|
||||
example, another note).
|
||||
|
||||
-c <object>::
|
||||
--reedit-message=<object>::
|
||||
@ -286,8 +285,6 @@ $ blob=$(git hash-object -w a.out)
|
||||
$ git notes --ref=built add -C "$blob" HEAD
|
||||
------------
|
||||
|
||||
(You cannot simply use `git notes --ref=built add -F a.out HEAD`
|
||||
because that is not binary-safe.)
|
||||
Of course, it doesn't make much sense to display non-text-format notes
|
||||
with 'git log', so if you use such notes, you'll probably need to write
|
||||
some special-purpose tools to do something useful with them.
|
||||
|
@ -162,12 +162,6 @@ useful if you write an alias or script around 'git push'.
|
||||
is specified. This flag forces progress status even if the
|
||||
standard error stream is not directed to a terminal.
|
||||
|
||||
--recurse-submodules=check::
|
||||
Check whether all submodule commits used by the revisions to be
|
||||
pushed are available on a remote tracking branch. Otherwise the
|
||||
push will be aborted and the command will exit with non-zero status.
|
||||
|
||||
|
||||
include::urls-remotes.txt[]
|
||||
|
||||
OUTPUT
|
||||
@ -333,12 +327,12 @@ a case where you do mean to lose history.
|
||||
Examples
|
||||
--------
|
||||
|
||||
`git push`::
|
||||
git push::
|
||||
Works like `git push <remote>`, where <remote> is the
|
||||
current branch's remote (or `origin`, if no remote is
|
||||
configured for the current branch).
|
||||
|
||||
`git push origin`::
|
||||
git push origin::
|
||||
Without additional configuration, works like
|
||||
`git push origin :`.
|
||||
+
|
||||
@ -350,45 +344,45 @@ use `git config remote.origin.push HEAD`. Any valid <refspec> (like
|
||||
the ones in the examples below) can be configured as the default for
|
||||
`git push origin`.
|
||||
|
||||
`git push origin :`::
|
||||
git push origin :::
|
||||
Push "matching" branches to `origin`. See
|
||||
<refspec> in the <<OPTIONS,OPTIONS>> section above for a
|
||||
description of "matching" branches.
|
||||
|
||||
`git push origin master`::
|
||||
git push origin master::
|
||||
Find a ref that matches `master` in the source repository
|
||||
(most likely, it would find `refs/heads/master`), and update
|
||||
the same ref (e.g. `refs/heads/master`) in `origin` repository
|
||||
with it. If `master` did not exist remotely, it would be
|
||||
created.
|
||||
|
||||
`git push origin HEAD`::
|
||||
git push origin HEAD::
|
||||
A handy way to push the current branch to the same name on the
|
||||
remote.
|
||||
|
||||
`git push origin master:satellite/master dev:satellite/dev`::
|
||||
git push origin master:satellite/master dev:satellite/dev::
|
||||
Use the source ref that matches `master` (e.g. `refs/heads/master`)
|
||||
to update the ref that matches `satellite/master` (most probably
|
||||
`refs/remotes/satellite/master`) in the `origin` repository, then
|
||||
do the same for `dev` and `satellite/dev`.
|
||||
|
||||
`git push origin HEAD:master`::
|
||||
git push origin HEAD:master::
|
||||
Push the current branch to the remote ref matching `master` in the
|
||||
`origin` repository. This form is convenient to push the current
|
||||
branch without thinking about its local name.
|
||||
|
||||
`git push origin master:refs/heads/experimental`::
|
||||
git push origin master:refs/heads/experimental::
|
||||
Create the branch `experimental` in the `origin` repository
|
||||
by copying the current `master` branch. This form is only
|
||||
needed to create a new branch or tag in the remote repository when
|
||||
the local name and the remote name are different; otherwise,
|
||||
the ref name on its own will work.
|
||||
|
||||
`git push origin :experimental`::
|
||||
git push origin :experimental::
|
||||
Find a ref that matches `experimental` in the `origin` repository
|
||||
(e.g. `refs/heads/experimental`), and delete it.
|
||||
|
||||
`git push origin {plus}dev:master`::
|
||||
git push origin {plus}dev:master::
|
||||
Update the origin repository's master branch with the dev branch,
|
||||
allowing non-fast-forward updates. *This can leave unreferenced
|
||||
commits dangling in the origin repository.* Consider the
|
||||
|
@ -83,11 +83,10 @@ OPTIONS
|
||||
|
||||
--prefix=<prefix>/::
|
||||
Keep the current index contents, and read the contents
|
||||
of the named tree-ish under the directory at `<prefix>`. The
|
||||
original index file cannot have anything at the path
|
||||
`<prefix>` itself, nor anything in the `<prefix>/`
|
||||
directory. Note that the `<prefix>/` value must end
|
||||
with a slash.
|
||||
of the named tree-ish under the directory at `<prefix>`.
|
||||
The command will refuse to overwrite entries that already
|
||||
existed in the original index file. Note that the `<prefix>/`
|
||||
value must end with a slash.
|
||||
|
||||
--exclude-per-directory=<gitignore>::
|
||||
When running the command with `-u` and `-m` options, the
|
||||
|
@ -150,7 +150,7 @@ if the repository is packed and is served via a dumb transport.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
linkgit:git-send-pack[1], linkgit:gitnamespaces[7]
|
||||
linkgit:git-send-pack[1]
|
||||
|
||||
GIT
|
||||
---
|
||||
|
@ -35,19 +35,19 @@ GIT_TRANSLOOP_DEBUG::
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
`git fetch fd::17 master`::
|
||||
git fetch fd::17 master::
|
||||
Fetch master, using file descriptor #17 to communicate with
|
||||
git-upload-pack.
|
||||
|
||||
`git fetch fd::17/foo master`::
|
||||
git fetch fd::17/foo master::
|
||||
Same as above.
|
||||
|
||||
`git push fd::7,8 master (as URL)`::
|
||||
git push fd::7,8 master (as URL)::
|
||||
Push master, using file descriptor #7 to read data from
|
||||
git-receive-pack and file descriptor #8 to write data to
|
||||
same service.
|
||||
|
||||
`git push fd::7,8/bar master`::
|
||||
git push fd::7,8/bar master::
|
||||
Same as above.
|
||||
|
||||
Documentation
|
||||
|
@ -24,141 +24,22 @@ output. Because a remote helper runs as an independent process from
|
||||
git, there is no need to re-link git to add a new helper, nor any
|
||||
need to link the helper with the implementation of git.
|
||||
|
||||
Every helper must support the "capabilities" command, which git
|
||||
uses to determine what other commands the helper will accept. Those
|
||||
other commands can be used to discover and update remote refs,
|
||||
transport objects between the object database and the remote repository,
|
||||
and update the local object store.
|
||||
Every helper must support the "capabilities" command, which git will
|
||||
use to determine what other commands the helper will accept. Other
|
||||
commands generally concern facilities like discovering and updating
|
||||
remote refs, transporting objects between the object database and
|
||||
the remote repository, and updating the local object store.
|
||||
|
||||
Helpers supporting the 'fetch' capability can discover refs from the
|
||||
remote repository and transfer objects reachable from those refs to
|
||||
the local object store. Helpers supporting the 'push' capability can
|
||||
transfer local objects to the remote repository and update remote refs.
|
||||
|
||||
Git comes with a "curl" family of remote helpers, that handle various
|
||||
transport protocols, such as 'git-remote-http', 'git-remote-https',
|
||||
'git-remote-ftp' and 'git-remote-ftps'. They implement the capabilities
|
||||
'fetch', 'option', and 'push'.
|
||||
|
||||
INPUT FORMAT
|
||||
------------
|
||||
|
||||
Git sends the remote helper a list of commands on standard input, one
|
||||
per line. The first command is always the 'capabilities' command, in
|
||||
response to which the remote helper must print a list of the
|
||||
capabilities it supports (see below) followed by a blank line. The
|
||||
response to the capabilities command determines what commands Git uses
|
||||
in the remainder of the command stream.
|
||||
|
||||
The command stream is terminated by a blank line. In some cases
|
||||
(indicated in the documentation of the relevant commands), this blank
|
||||
line is followed by a payload in some other protocol (e.g., the pack
|
||||
protocol), while in others it indicates the end of input.
|
||||
|
||||
Capabilities
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Each remote helper is expected to support only a subset of commands.
|
||||
The operations a helper supports are declared to git in the response
|
||||
to the `capabilities` command (see COMMANDS, below).
|
||||
|
||||
'option'::
|
||||
For specifying settings like `verbosity` (how much output to
|
||||
write to stderr) and `depth` (how much history is wanted in the
|
||||
case of a shallow clone) that affect how other commands are
|
||||
carried out.
|
||||
|
||||
'connect'::
|
||||
For fetching and pushing using git's native packfile protocol
|
||||
that requires a bidirectional, full-duplex connection.
|
||||
|
||||
'push'::
|
||||
For listing remote refs and pushing specified objects from the
|
||||
local object store to remote refs.
|
||||
|
||||
'fetch'::
|
||||
For listing remote refs and fetching the associated history to
|
||||
the local object store.
|
||||
|
||||
'import'::
|
||||
For listing remote refs and fetching the associated history as
|
||||
a fast-import stream.
|
||||
|
||||
'refspec' <refspec>::
|
||||
This modifies the 'import' capability, allowing the produced
|
||||
fast-import stream to modify refs in a private namespace
|
||||
instead of writing to refs/heads or refs/remotes directly.
|
||||
It is recommended that all importers providing the 'import'
|
||||
capability use this.
|
||||
+
|
||||
A helper advertising the capability
|
||||
`refspec refs/heads/{asterisk}:refs/svn/origin/branches/{asterisk}`
|
||||
is saying that, when it is asked to `import refs/heads/topic`, the
|
||||
stream it outputs will update the `refs/svn/origin/branches/topic`
|
||||
ref.
|
||||
+
|
||||
This capability can be advertised multiple times. The first
|
||||
applicable refspec takes precedence. The left-hand of refspecs
|
||||
advertised with this capability must cover all refs reported by
|
||||
the list command. If no 'refspec' capability is advertised,
|
||||
there is an implied `refspec {asterisk}:{asterisk}`.
|
||||
|
||||
Capabilities for Pushing
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
'connect'::
|
||||
Can attempt to connect to 'git receive-pack' (for pushing),
|
||||
'git upload-pack', etc for communication using the
|
||||
packfile protocol.
|
||||
+
|
||||
Supported commands: 'connect'.
|
||||
|
||||
'push'::
|
||||
Can discover remote refs and push local commits and the
|
||||
history leading up to them to new or existing remote refs.
|
||||
+
|
||||
Supported commands: 'list for-push', 'push'.
|
||||
|
||||
If a helper advertises both 'connect' and 'push', git will use
|
||||
'connect' if possible and fall back to 'push' if the helper requests
|
||||
so when connecting (see the 'connect' command under COMMANDS).
|
||||
|
||||
Capabilities for Fetching
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
'connect'::
|
||||
Can try to connect to 'git upload-pack' (for fetching),
|
||||
'git receive-pack', etc for communication using the
|
||||
packfile protocol.
|
||||
+
|
||||
Supported commands: 'connect'.
|
||||
|
||||
'fetch'::
|
||||
Can discover remote refs and transfer objects reachable from
|
||||
them to the local object store.
|
||||
+
|
||||
Supported commands: 'list', 'fetch'.
|
||||
|
||||
'import'::
|
||||
Can discover remote refs and output objects reachable from
|
||||
them as a stream in fast-import format.
|
||||
+
|
||||
Supported commands: 'list', 'import'.
|
||||
|
||||
If a helper advertises 'connect', git will use it if possible and
|
||||
fall back to another capability if the helper requests so when
|
||||
connecting (see the 'connect' command under COMMANDS).
|
||||
When choosing between 'fetch' and 'import', git prefers 'fetch'.
|
||||
Other frontends may have some other order of preference.
|
||||
|
||||
'refspec' <refspec>::
|
||||
This modifies the 'import' capability.
|
||||
+
|
||||
A helper advertising
|
||||
`refspec refs/heads/{asterisk}:refs/svn/origin/branches/{asterisk}`
|
||||
in its capabilities is saying that, when it handles
|
||||
`import refs/heads/topic`, the stream it outputs will update the
|
||||
`refs/svn/origin/branches/topic` ref.
|
||||
+
|
||||
This capability can be advertised multiple times. The first
|
||||
applicable refspec takes precedence. The left-hand of refspecs
|
||||
advertised with this capability must cover all refs reported by
|
||||
the list command. If no 'refspec' capability is advertised,
|
||||
there is an implied `refspec {asterisk}:{asterisk}`.
|
||||
|
||||
INVOCATION
|
||||
----------
|
||||
|
||||
@ -167,9 +48,6 @@ arguments. The first argument specifies a remote repository as in git;
|
||||
it is either the name of a configured remote or a URL. The second
|
||||
argument specifies a URL; it is usually of the form
|
||||
'<transport>://<address>', but any arbitrary string is possible.
|
||||
The 'GIT_DIR' environment variable is set up for the remote helper
|
||||
and can be used to determine where to store additional data or from
|
||||
which directory to invoke auxiliary git commands.
|
||||
|
||||
When git encounters a URL of the form '<transport>://<address>', where
|
||||
'<transport>' is a protocol that it cannot handle natively, it
|
||||
@ -241,22 +119,7 @@ Supported if the helper has the "fetch" capability.
|
||||
'push' +<src>:<dst>::
|
||||
Pushes the given local <src> commit or branch to the
|
||||
remote branch described by <dst>. A batch sequence of
|
||||
one or more 'push' commands is terminated with a blank line
|
||||
(if there is only one reference to push, a single 'push' command
|
||||
is followed by a blank line). For example, the following would
|
||||
be two batches of 'push', the first asking the remote-helper
|
||||
to push the local ref 'master' to the remote ref 'master' and
|
||||
the local 'HEAD' to the remote 'branch', and the second
|
||||
asking to push ref 'foo' to ref 'bar' (forced update requested
|
||||
by the '+').
|
||||
+
|
||||
------------
|
||||
push refs/heads/master:refs/heads/master
|
||||
push HEAD:refs/heads/branch
|
||||
\n
|
||||
push +refs/heads/foo:refs/heads/bar
|
||||
\n
|
||||
------------
|
||||
one or more push commands is terminated with a blank line.
|
||||
+
|
||||
Zero or more protocol options may be entered after the last 'push'
|
||||
command, before the batch's terminating blank line.
|
||||
@ -281,11 +144,6 @@ Supported if the helper has the "push" capability.
|
||||
Especially useful for interoperability with a foreign versioning
|
||||
system.
|
||||
+
|
||||
Just like 'push', a batch sequence of one or more 'import' is
|
||||
terminated with a blank line. For each batch of 'import', the remote
|
||||
helper should produce a fast-import stream terminated by a 'done'
|
||||
command.
|
||||
+
|
||||
Supported if the helper has the "import" capability.
|
||||
|
||||
'connect' <service>::
|
||||
@ -310,6 +168,26 @@ completing a valid response for the current command.
|
||||
Additional commands may be supported, as may be determined from
|
||||
capabilities reported by the helper.
|
||||
|
||||
CAPABILITIES
|
||||
------------
|
||||
|
||||
'fetch'::
|
||||
'option'::
|
||||
'push'::
|
||||
'import'::
|
||||
'connect'::
|
||||
This helper supports the corresponding command with the same name.
|
||||
|
||||
'refspec' 'spec'::
|
||||
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/{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 "{asterisk}:{asterisk}"
|
||||
|
||||
REF LIST ATTRIBUTES
|
||||
-------------------
|
||||
|
||||
@ -362,8 +240,6 @@ SEE ALSO
|
||||
--------
|
||||
linkgit:git-remote[1]
|
||||
|
||||
linkgit:git-remote-testgit[1]
|
||||
|
||||
GIT
|
||||
---
|
||||
Part of the linkgit:git[1] suite
|
||||
|
@ -1,30 +0,0 @@
|
||||
git-remote-testgit(1)
|
||||
=====================
|
||||
|
||||
NAME
|
||||
----
|
||||
git-remote-testgit - Example remote-helper
|
||||
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
git clone testgit::<source-repo> [<destination>]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
This command is a simple remote-helper, that is used both as a
|
||||
testcase for the remote-helper functionality, and as an example to
|
||||
show remote-helper authors one possible implementation.
|
||||
|
||||
The best way to learn more is to read the comments and source code in
|
||||
'git-remote-testgit.py'.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
linkgit:git-remote-helpers[1]
|
||||
|
||||
GIT
|
||||
---
|
||||
Part of the linkgit:git[1] suite
|
@ -180,10 +180,6 @@ print a message to stderr and exit with nonzero status.
|
||||
<args>...::
|
||||
Flags and parameters to be parsed.
|
||||
|
||||
--resolve-git-dir <path>::
|
||||
Check if <path> is a valid git-dir or a git-file pointing to a valid
|
||||
git-dir. If <path> is a valid git-dir the resolved path to git-dir will
|
||||
be printed.
|
||||
|
||||
include::revisions.txt[]
|
||||
|
||||
|
@ -9,8 +9,6 @@ SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git revert' [--edit | --no-edit] [-n] [-m parent-number] [-s] <commit>...
|
||||
'git revert' --reset
|
||||
'git revert' --continue
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@ -93,18 +91,14 @@ effect to your index in a row.
|
||||
Pass the merge strategy-specific option through to the
|
||||
merge strategy. See linkgit:git-merge[1] for details.
|
||||
|
||||
SEQUENCER SUBCOMMANDS
|
||||
---------------------
|
||||
include::sequencer.txt[]
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
`git revert HEAD~3`::
|
||||
git revert HEAD~3::
|
||||
|
||||
Revert the changes specified by the fourth last commit in HEAD
|
||||
and create a new commit with the reverted changes.
|
||||
|
||||
`git revert -n master{tilde}5..master{tilde}2`::
|
||||
git revert -n master{tilde}5..master{tilde}2::
|
||||
|
||||
Revert the changes done by commits from the fifth last commit
|
||||
in master (included) to the third last commit in master
|
||||
|
@ -137,7 +137,7 @@ git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
`git rm Documentation/\*.txt`::
|
||||
git rm Documentation/\*.txt::
|
||||
Removes all `*.txt` files from the index that are under the
|
||||
`Documentation` directory and any of its subdirectories.
|
||||
+
|
||||
@ -145,7 +145,7 @@ Note that the asterisk `*` is quoted from the shell in this
|
||||
example; this lets git, and not the shell, expand the pathnames
|
||||
of files and subdirectories under the `Documentation/` directory.
|
||||
|
||||
`git rm -f git-*.sh`::
|
||||
git rm -f git-*.sh::
|
||||
Because this example lets the shell expand the asterisk
|
||||
(i.e. you are listing the files explicitly), it
|
||||
does not remove `subdir/git-foo.sh`.
|
||||
|
@ -48,23 +48,23 @@ include::pretty-formats.txt[]
|
||||
EXAMPLES
|
||||
--------
|
||||
|
||||
`git show v1.0.0`::
|
||||
git show v1.0.0::
|
||||
Shows the tag `v1.0.0`, along with the object the tags
|
||||
points at.
|
||||
|
||||
`git show v1.0.0^\{tree\}`::
|
||||
git show v1.0.0^\{tree\}::
|
||||
Shows the tree pointed to by the tag `v1.0.0`.
|
||||
|
||||
`git show -s --format=%s v1.0.0^\{commit\}`::
|
||||
git show -s --format=%s v1.0.0^\{commit\}::
|
||||
Shows the subject of the commit pointed to by the
|
||||
tag `v1.0.0`.
|
||||
|
||||
`git show next~10:Documentation/README`::
|
||||
git show next~10:Documentation/README::
|
||||
Shows the contents of the file `Documentation/README` as
|
||||
they were current in the 10th last commit of the branch
|
||||
`next`.
|
||||
|
||||
`git show master:Makefile master:t/Makefile`::
|
||||
git show master:Makefile master:t/Makefile::
|
||||
Concatenates the contents of said Makefiles in the head
|
||||
of the branch `master`.
|
||||
|
||||
|
@ -13,8 +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]
|
||||
[-u|--include-untracked] [-a|--all] [<message>]]
|
||||
'git stash' [save [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet] [<message>]]
|
||||
'git stash' clear
|
||||
'git stash' create
|
||||
|
||||
@ -43,7 +42,7 @@ is also possible).
|
||||
OPTIONS
|
||||
-------
|
||||
|
||||
save [-p|--patch] [--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-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
|
||||
@ -55,11 +54,6 @@ save [-p|--patch] [--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--
|
||||
If the `--keep-index` option is used, all changes already added to the
|
||||
index are left intact.
|
||||
+
|
||||
If the `--include-untracked` option is used, all untracked files are also
|
||||
stashed and then cleaned up with `git clean`, leaving the working directory
|
||||
in a very clean state. If the `--all` option is used instead then the
|
||||
ignored files are stashed and cleaned in addition to the untracked files.
|
||||
+
|
||||
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
|
||||
|
@ -15,8 +15,7 @@ SYNOPSIS
|
||||
'git submodule' [--quiet] init [--] [<path>...]
|
||||
'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase]
|
||||
[--reference <repository>] [--merge] [--recursive] [--] [<path>...]
|
||||
'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) <n>]
|
||||
[commit] [--] [<path>...]
|
||||
'git submodule' [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
|
||||
'git submodule' [--quiet] foreach [--recursive] <command>
|
||||
'git submodule' [--quiet] sync [--] [<path>...]
|
||||
|
||||
@ -109,19 +108,12 @@ status::
|
||||
repository and `U` if the submodule has merge conflicts.
|
||||
This command is the default command for 'git submodule'.
|
||||
+
|
||||
If `--recursive` is specified, this command will recurse into nested
|
||||
If '--recursive' is specified, this command will recurse into nested
|
||||
submodules, and show their status as well.
|
||||
+
|
||||
If you are only interested in changes of the currently initialized
|
||||
submodules with respect to the commit recorded in the index or the HEAD,
|
||||
linkgit:git-status[1] and linkgit:git-diff[1] will provide that information
|
||||
too (and can also report changes to a submodule's work tree).
|
||||
|
||||
init::
|
||||
Initialize the submodules, i.e. register each submodule name
|
||||
and url found in .gitmodules into .git/config.
|
||||
It will also copy the value of `submodule.$name.update` into
|
||||
.git/config.
|
||||
The key used in .git/config is `submodule.$name.url`.
|
||||
This command does not alter existing information in .git/config.
|
||||
You can then customize the submodule clone URLs in .git/config
|
||||
@ -133,33 +125,26 @@ init::
|
||||
update::
|
||||
Update the registered submodules, i.e. clone missing submodules and
|
||||
checkout the commit specified in the index of the containing repository.
|
||||
This will make the submodules HEAD be detached unless `--rebase` or
|
||||
`--merge` is specified or the key `submodule.$name.update` is set to
|
||||
`rebase`, `merge` or `none`.
|
||||
This will make the submodules HEAD be detached unless '--rebase' or
|
||||
'--merge' is specified or the key `submodule.$name.update` is set to
|
||||
`rebase` or `merge`.
|
||||
+
|
||||
If the submodule is not yet initialized, and you just want to use the
|
||||
setting as stored in .gitmodules, you can automatically initialize the
|
||||
submodule with the `--init` option.
|
||||
submodule with the --init option.
|
||||
+
|
||||
If `--recursive` is specified, this command will recurse into the
|
||||
If '--recursive' is specified, this command will recurse into the
|
||||
registered submodules, and update any nested submodules within.
|
||||
+
|
||||
If the configuration key `submodule.$name.update` is set to `none` the
|
||||
submodule with name `$name` will not be updated by default. This can be
|
||||
overriden by adding `--checkout` to the command.
|
||||
|
||||
summary::
|
||||
Show commit summary between the given commit (defaults to HEAD) and
|
||||
working tree/index. For a submodule in question, a series of commits
|
||||
in the submodule between the given super project commit and the
|
||||
index or working tree (switched by `--cached`) are shown. If the option
|
||||
`--files` is given, show the series of commits in the submodule between
|
||||
index or working tree (switched by --cached) are shown. If the option
|
||||
--files is given, show the series of commits in the submodule between
|
||||
the index of the super project and the working tree of the submodule
|
||||
(this option doesn't allow to use the `--cached` option or to provide an
|
||||
(this option doesn't allow to use the --cached option or to provide an
|
||||
explicit commit).
|
||||
+
|
||||
Using the `--submodule=log` option with linkgit:git-diff[1] will provide that
|
||||
information too.
|
||||
|
||||
foreach::
|
||||
Evaluates an arbitrary shell command in each checked out submodule.
|
||||
@ -170,9 +155,9 @@ foreach::
|
||||
superproject, $sha1 is the commit as recorded in the superproject,
|
||||
and $toplevel is the absolute path to the top-level of the superproject.
|
||||
Any submodules defined in the superproject but not checked out are
|
||||
ignored by this command. Unless given `--quiet`, foreach prints the name
|
||||
ignored by this command. Unless given --quiet, foreach prints the name
|
||||
of each submodule before evaluating the command.
|
||||
If `--recursive` is given, submodules are traversed recursively (i.e.
|
||||
If --recursive is given, submodules are traversed recursively (i.e.
|
||||
the given shell command is evaluated in nested submodules as well).
|
||||
A non-zero return from the command in any submodule causes
|
||||
the processing to terminate. This can be overridden by adding '|| :'
|
||||
@ -252,18 +237,13 @@ OPTIONS
|
||||
If the key `submodule.$name.update` is set to `rebase`, this option is
|
||||
implicit.
|
||||
|
||||
--init::
|
||||
This option is only valid for the update command.
|
||||
Initialize all submodules for which "git submodule init" has not been
|
||||
called so far before updating.
|
||||
|
||||
--reference <repository>::
|
||||
This option is only valid for add and update commands. These
|
||||
commands sometimes need to clone a remote repository. In this case,
|
||||
this option will be passed to the linkgit:git-clone[1] command.
|
||||
+
|
||||
*NOTE*: Do *not* use this option unless you have read the note
|
||||
for linkgit:git-clone[1]'s `--reference` and `--shared` options carefully.
|
||||
for linkgit:git-clone[1]'s --reference and --shared options carefully.
|
||||
|
||||
--recursive::
|
||||
This option is only valid for foreach, update and status commands.
|
||||
|
@ -157,17 +157,6 @@ Skip "branches" and "tags" of first level directories;;
|
||||
affecting the working tree; and the 'rebase' command will be
|
||||
able to update the working tree with the latest changes.
|
||||
|
||||
--preserve-empty-dirs;;
|
||||
Create a placeholder file in the local Git repository for each
|
||||
empty directory fetched from Subversion. This includes directories
|
||||
that become empty by removing all entries in the Subversion
|
||||
repository (but not the directory itself). The placeholder files
|
||||
are also tracked and removed when no longer necessary.
|
||||
|
||||
--placeholder-filename=<filename>;;
|
||||
Set the name of placeholder files created by --preserve-empty-dirs.
|
||||
Default: ".gitignore"
|
||||
|
||||
'rebase'::
|
||||
This fetches revisions from the SVN parent of the current HEAD
|
||||
and rebases the current (uncommitted to SVN) work against it.
|
||||
@ -222,25 +211,8 @@ discouraged.
|
||||
Add the given merge information during the dcommit
|
||||
(e.g. `--mergeinfo="/branches/foo:1-10"`). All svn server versions can
|
||||
store this information (as a property), and svn clients starting from
|
||||
version 1.5 can make use of it. To specify merge information from multiple
|
||||
branches, use a single space character between the branches
|
||||
(`--mergeinfo="/branches/foo:1-10 /branches/bar:3,5-6,8"`)
|
||||
+
|
||||
[verse]
|
||||
config key: svn.pushmergeinfo
|
||||
+
|
||||
This option will cause git-svn to attempt to automatically populate the
|
||||
svn:mergeinfo property in the SVN repository when possible. Currently, this can
|
||||
only be done when dcommitting non-fast-forward merges where all parents but the
|
||||
first have already been pushed into SVN.
|
||||
|
||||
--interactive;;
|
||||
Ask the user to confirm that a patch set should actually be sent to SVN.
|
||||
For each patch, one may answer "yes" (accept this patch), "no" (discard this
|
||||
patch), "all" (accept all patches), or "quit".
|
||||
+
|
||||
'git svn dcommit' returns immediately if answer if "no" or "quit", without
|
||||
commiting anything to SVN.
|
||||
version 1.5 can make use of it. 'git svn' currently does not use it
|
||||
and does not set it automatically.
|
||||
|
||||
'branch'::
|
||||
Create a branch in the SVN repository.
|
||||
@ -326,7 +298,7 @@ Any other arguments are passed directly to 'git log'
|
||||
Show what revision and author last modified each line of a file. The
|
||||
output of this mode is format-compatible with the output of
|
||||
`svn blame' by default. Like the SVN blame command,
|
||||
local uncommitted changes in the working tree are ignored;
|
||||
local uncommitted changes in the working copy are ignored;
|
||||
the version of the file in the HEAD revision is annotated. Unknown
|
||||
arguments are passed directly to 'git blame'.
|
||||
+
|
||||
|
@ -43,15 +43,12 @@ GnuPG key for signing.
|
||||
OPTIONS
|
||||
-------
|
||||
-a::
|
||||
--annotate::
|
||||
Make an unsigned, annotated tag object
|
||||
|
||||
-s::
|
||||
--sign::
|
||||
Make a GPG-signed tag, using the default e-mail address's key
|
||||
|
||||
-u <key-id>::
|
||||
--local-user=<key-id>::
|
||||
Make a GPG-signed tag, using the given key
|
||||
|
||||
-f::
|
||||
@ -59,11 +56,9 @@ OPTIONS
|
||||
Replace an existing tag with the given name (instead of failing)
|
||||
|
||||
-d::
|
||||
--delete::
|
||||
Delete existing tags with the given names.
|
||||
|
||||
-v::
|
||||
--verify::
|
||||
Verify the gpg signature of the given tag names.
|
||||
|
||||
-n<num>::
|
||||
@ -74,7 +69,6 @@ OPTIONS
|
||||
If the tag is not annotated, the commit message is displayed instead.
|
||||
|
||||
-l <pattern>::
|
||||
--list <pattern>::
|
||||
List tags with names that match the given pattern (or all if no
|
||||
pattern is given). Running "git tag" without arguments also
|
||||
lists all tags. The pattern is a shell wildcard (i.e., matched
|
||||
@ -85,7 +79,6 @@ OPTIONS
|
||||
Only list tags which contain the specified commit.
|
||||
|
||||
-m <msg>::
|
||||
--message=<msg>::
|
||||
Use the given tag message (instead of prompting).
|
||||
If multiple `-m` options are given, their values are
|
||||
concatenated as separate paragraphs.
|
||||
@ -93,7 +86,6 @@ OPTIONS
|
||||
is given.
|
||||
|
||||
-F <file>::
|
||||
--file=<file>::
|
||||
Take the tag message from the given file. Use '-' to
|
||||
read the message from the standard input.
|
||||
Implies `-a` if none of `-a`, `-s`, or `-u <key-id>`
|
||||
|
@ -53,26 +53,26 @@ tar.umask::
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
`git tar-tree HEAD junk | (cd /var/tmp/ && tar xf -)`::
|
||||
git tar-tree HEAD junk | (cd /var/tmp/ && tar xf -)::
|
||||
|
||||
Create a tar archive that contains the contents of the
|
||||
latest commit on the current branch, and extracts it in
|
||||
`/var/tmp/junk` directory.
|
||||
|
||||
`git tar-tree v1.4.0 git-1.4.0 | gzip >git-1.4.0.tar.gz`::
|
||||
git tar-tree v1.4.0 git-1.4.0 | gzip >git-1.4.0.tar.gz::
|
||||
|
||||
Create a tarball for v1.4.0 release.
|
||||
|
||||
`git tar-tree v1.4.0{caret}\{tree\} git-1.4.0 | gzip >git-1.4.0.tar.gz`::
|
||||
git tar-tree v1.4.0{caret}\{tree\} git-1.4.0 | gzip >git-1.4.0.tar.gz::
|
||||
|
||||
Create a tarball for v1.4.0 release, but without a
|
||||
global extended pax header.
|
||||
|
||||
`git tar-tree --remote=example.com:git.git v1.4.0 >git-1.4.0.tar`::
|
||||
git tar-tree --remote=example.com:git.git v1.4.0 >git-1.4.0.tar::
|
||||
|
||||
Get a tarball v1.4.0 from example.com.
|
||||
|
||||
`git tar-tree HEAD:Documentation/ git-docs > git-1.4.0-docs.tar`::
|
||||
git tar-tree HEAD:Documentation/ git-docs > git-1.4.0-docs.tar::
|
||||
|
||||
Put everything in the current head's Documentation/ directory
|
||||
into 'git-1.4.0-docs.tar', with the prefix 'git-docs/'.
|
||||
|
@ -34,10 +34,6 @@ OPTIONS
|
||||
<directory>::
|
||||
The repository to sync from.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
linkgit:gitnamespaces[7]
|
||||
|
||||
GIT
|
||||
---
|
||||
Part of the linkgit:git[1] suite
|
||||
|
@ -53,12 +53,12 @@ include::pretty-formats.txt[]
|
||||
|
||||
Examples
|
||||
--------
|
||||
`git whatchanged -p v2.6.12.. include/scsi drivers/scsi`::
|
||||
git whatchanged -p v2.6.12.. include/scsi drivers/scsi::
|
||||
|
||||
Show as patches the commits since version 'v2.6.12' that changed
|
||||
any file in the include/scsi or drivers/scsi subdirectories
|
||||
|
||||
`git whatchanged --since="2 weeks ago" \-- gitk`::
|
||||
git whatchanged --since="2 weeks ago" \-- gitk::
|
||||
|
||||
Show the changes during the last two weeks to the file 'gitk'.
|
||||
The "--" is necessary to avoid confusion with the *branch* named
|
||||
|
@ -10,8 +10,8 @@ SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'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>] [--namespace=<name>]
|
||||
[-p|--paginate|--no-pager] [--no-replace-objects]
|
||||
[--bare] [--git-dir=<path>] [--work-tree=<path>]
|
||||
[-c <name>=<value>]
|
||||
[--help] <command> [<args>]
|
||||
|
||||
@ -44,15 +44,11 @@ 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.7.1/git.html[documentation for release 1.7.7.1]
|
||||
|
||||
* release notes for
|
||||
link:RelNotes/1.7.7.1.txt[1.7.7.1],
|
||||
link:RelNotes/1.7.7.txt[1.7.7].
|
||||
|
||||
* link:v1.7.6.4/git.html[documentation for release 1.7.6.4]
|
||||
* link:v1.7.6.6/git.html[documentation for release 1.7.6.6]
|
||||
|
||||
* release notes for
|
||||
link:RelNotes/1.7.6.6.txt[1.7.6.6],
|
||||
link:RelNotes/1.7.6.5.txt[1.7.6.5],
|
||||
link:RelNotes/1.7.6.4.txt[1.7.6.4],
|
||||
link:RelNotes/1.7.6.3.txt[1.7.6.3],
|
||||
link:RelNotes/1.7.6.2.txt[1.7.6.2],
|
||||
@ -340,11 +336,6 @@ help ...`.
|
||||
variable (see core.worktree in linkgit:git-config[1] for a
|
||||
more detailed discussion).
|
||||
|
||||
--namespace=<path>::
|
||||
Set the git namespace. See linkgit:gitnamespaces[7] for more
|
||||
details. Equivalent to setting the `GIT_NAMESPACE` environment
|
||||
variable.
|
||||
|
||||
--bare::
|
||||
Treat the repository as a bare repository. If GIT_DIR
|
||||
environment is not set, it is set to the current working
|
||||
@ -608,10 +599,6 @@ git so take care if using Cogito etc.
|
||||
This can also be controlled by the '--work-tree' command line
|
||||
option and the core.worktree configuration variable.
|
||||
|
||||
'GIT_NAMESPACE'::
|
||||
Set the git namespace; see linkgit:gitnamespaces[7] for details.
|
||||
The '--namespace' command-line option also sets this value.
|
||||
|
||||
'GIT_CEILING_DIRECTORIES'::
|
||||
This should be a colon-separated list of absolute paths.
|
||||
If set, it is a list of directories that git should not chdir
|
||||
|
@ -955,9 +955,6 @@ frotz unspecified
|
||||
----------------------------------------------------------------
|
||||
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
linkgit:git-check-attr[1].
|
||||
|
||||
GIT
|
||||
---
|
||||
|
@ -1,82 +0,0 @@
|
||||
gitnamespaces(7)
|
||||
================
|
||||
|
||||
NAME
|
||||
----
|
||||
gitnamespaces - Git namespaces
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
GIT_NAMESPACE=<namespace> 'git upload-pack'
|
||||
GIT_NAMESPACE=<namespace> 'git receive-pack'
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
Git supports dividing the refs of a single repository into multiple
|
||||
namespaces, each of which has its own branches, tags, and HEAD. Git can
|
||||
expose each namespace as an independent repository to pull from and push
|
||||
to, while sharing the object store, and exposing all the refs to
|
||||
operations such as linkgit:git-gc[1].
|
||||
|
||||
Storing multiple repositories as namespaces of a single repository
|
||||
avoids storing duplicate copies of the same objects, such as when
|
||||
storing multiple branches of the same source. The alternates mechanism
|
||||
provides similar support for avoiding duplicates, but alternates do not
|
||||
prevent duplication between new objects added to the repositories
|
||||
without ongoing maintenance, while namespaces do.
|
||||
|
||||
To specify a namespace, set the `GIT_NAMESPACE` environment variable to
|
||||
the namespace. For each ref namespace, git stores the corresponding
|
||||
refs in a directory under `refs/namespaces/`. For example,
|
||||
`GIT_NAMESPACE=foo` will store refs under `refs/namespaces/foo/`. You
|
||||
can also specify namespaces via the `--namespace` option to
|
||||
linkgit:git[1].
|
||||
|
||||
Note that namespaces which include a `/` will expand to a hierarchy of
|
||||
namespaces; for example, `GIT_NAMESPACE=foo/bar` will store refs under
|
||||
`refs/namespaces/foo/refs/namespaces/bar/`. This makes paths in
|
||||
`GIT_NAMESPACE` behave hierarchically, so that cloning with
|
||||
`GIT_NAMESPACE=foo/bar` produces the same result as cloning with
|
||||
`GIT_NAMESPACE=foo` and cloning from that repo with `GIT_NAMESPACE=bar`. It
|
||||
also avoids ambiguity with strange namespace paths such as `foo/refs/heads/`,
|
||||
which could otherwise generate directory/file conflicts within the `refs`
|
||||
directory.
|
||||
|
||||
linkgit:git-upload-pack[1] and linkgit:git-receive-pack[1] rewrite the
|
||||
names of refs as specified by `GIT_NAMESPACE`. git-upload-pack and
|
||||
git-receive-pack will ignore all references outside the specified
|
||||
namespace.
|
||||
|
||||
The smart HTTP server, linkgit:git-http-backend[1], will pass
|
||||
GIT_NAMESPACE through to the backend programs; see
|
||||
linkgit:git-http-backend[1] for sample configuration to expose
|
||||
repository namespaces as repositories.
|
||||
|
||||
For a simple local test, you can use linkgit:git-remote-ext[1]:
|
||||
|
||||
----------
|
||||
git clone ext::'git --namespace=foo %s /tmp/prefixed.git'
|
||||
----------
|
||||
|
||||
SECURITY
|
||||
--------
|
||||
|
||||
Anyone with access to any namespace within a repository can potentially
|
||||
access objects from any other namespace stored in the same repository.
|
||||
You can't directly say "give me object ABCD" if you don't have a ref to
|
||||
it, but you can do some other sneaky things like:
|
||||
|
||||
. Claiming to push ABCD, at which point the server will optimize out the
|
||||
need for you to actually send it. Now you have a ref to ABCD and can
|
||||
fetch it (claiming not to have it, of course).
|
||||
|
||||
. Requesting other refs, claiming that you have ABCD, at which point the
|
||||
server may generate deltas against ABCD.
|
||||
|
||||
None of this causes a problem if you only host public repositories, or
|
||||
if everyone who may read one namespace may also read everything in every
|
||||
other namespace (for instance, if everyone in an organization has read
|
||||
permission to every repository).
|
@ -23,25 +23,32 @@ objects::
|
||||
Object store associated with this repository. Usually
|
||||
an object store is self sufficient (i.e. all the objects
|
||||
that are referred to by an object found in it are also
|
||||
found in it), but there are a few ways to violate it.
|
||||
found in it), but there are couple of ways to violate
|
||||
it.
|
||||
+
|
||||
. You could have an incomplete but locally usable repository
|
||||
by creating a shallow clone. See linkgit:git-clone[1].
|
||||
. You could be using the `objects/info/alternates` or
|
||||
`$GIT_ALTERNATE_OBJECT_DIRECTORIES` mechanisms to 'borrow'
|
||||
. You could populate the repository by running a commit walker
|
||||
without `-a` option. Depending on which options are given, you
|
||||
could have only commit objects without associated blobs and
|
||||
trees this way, for example. A repository with this kind of
|
||||
incomplete object store is not suitable to be published to the
|
||||
outside world but sometimes useful for private repository.
|
||||
. You also could have an incomplete but locally usable repository
|
||||
by cloning shallowly. See linkgit:git-clone[1].
|
||||
. You can be using `objects/info/alternates` mechanism, or
|
||||
`$GIT_ALTERNATE_OBJECT_DIRECTORIES` mechanism to 'borrow'
|
||||
objects from other object stores. A repository with this kind
|
||||
of incomplete object store is not suitable to be published for
|
||||
use with dumb transports but otherwise is OK as long as
|
||||
`objects/info/alternates` points at the object stores it
|
||||
borrows from.
|
||||
`objects/info/alternates` points at the right object stores
|
||||
it borrows from.
|
||||
|
||||
objects/[0-9a-f][0-9a-f]::
|
||||
A newly created object is stored in its own file.
|
||||
The objects are splayed over 256 subdirectories using
|
||||
the first two characters of the sha1 object name to
|
||||
keep the number of directory entries in `objects`
|
||||
itself to a manageable number. Objects found
|
||||
here are often called 'unpacked' (or 'loose') objects.
|
||||
Traditionally, each object is stored in its own file.
|
||||
They are split into 256 subdirectories using the first
|
||||
two letters from its object name to keep the number of
|
||||
directory entries `objects` directory itself needs to
|
||||
hold. Objects found here are often called 'unpacked'
|
||||
(or 'loose') objects.
|
||||
|
||||
objects/pack::
|
||||
Packs (files that store many object in compressed form,
|
||||
@ -78,7 +85,7 @@ objects/info/http-alternates::
|
||||
|
||||
refs::
|
||||
References are stored in subdirectories of this
|
||||
directory. The 'git prune' command knows to preserve
|
||||
directory. The 'git prune' command knows to keep
|
||||
objects reachable from refs found in this directory and
|
||||
its subdirectories.
|
||||
|
||||
@ -112,17 +119,16 @@ HEAD::
|
||||
+
|
||||
HEAD can also record a specific commit directly, instead of
|
||||
being a symref to point at the current branch. Such a state
|
||||
is often called 'detached HEAD.' See linkgit:git-checkout[1]
|
||||
for details.
|
||||
is often called 'detached HEAD', and almost all commands work
|
||||
identically as normal. See linkgit:git-checkout[1] for
|
||||
details.
|
||||
|
||||
branches::
|
||||
A slightly deprecated way to store shorthands to be used
|
||||
to specify a URL to 'git fetch', 'git pull' and 'git push'.
|
||||
A file can be stored as `branches/<name>` and then
|
||||
'name' can be given to these commands in place of
|
||||
'repository' argument. See the REMOTES section in
|
||||
linkgit:git-fetch[1] for details. This mechanism is legacy
|
||||
and not likely to be found in modern repositories.
|
||||
to specify URL to 'git fetch', 'git pull' and 'git push'
|
||||
commands is to store a file in `branches/<name>` and
|
||||
give 'name' to these commands in place of 'repository'
|
||||
argument.
|
||||
|
||||
hooks::
|
||||
Hooks are customization scripts used by various git
|
||||
@ -167,11 +173,9 @@ info/exclude::
|
||||
at it. See also: linkgit:gitignore[5].
|
||||
|
||||
remotes::
|
||||
Stores shorthands for URL and default refnames for use
|
||||
when interacting with remote repositories via 'git fetch',
|
||||
'git pull' and 'git push' commands. See the REMOTES section
|
||||
in linkgit:git-fetch[1] for details. This mechanism is legacy
|
||||
and not likely to be found in modern repositories.
|
||||
Stores shorthands to be used to give URL and default
|
||||
refnames to interact with remote repository to
|
||||
'git fetch', 'git pull' and 'git push' commands.
|
||||
|
||||
logs::
|
||||
Records of changes made to refs are stored in this
|
||||
|
@ -1,889 +0,0 @@
|
||||
gitweb.conf(5)
|
||||
==============
|
||||
|
||||
NAME
|
||||
----
|
||||
gitweb.conf - Gitweb (git web interface) configuration file
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
/etc/gitweb.conf, /etc/gitweb-common.conf, $GITWEBDIR/gitweb_config.perl
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
The gitweb CGI script for viewing Git repositories over the web uses a
|
||||
perl script fragment as its configuration file. You can set variables
|
||||
using "`our $variable = value`"; text from a "#" character until the
|
||||
end of a line is ignored. See *perlsyn*(1) for details.
|
||||
|
||||
An example:
|
||||
|
||||
# gitweb configuration file for http://git.example.org
|
||||
#
|
||||
our $projectroot = "/srv/git"; # FHS recommendation
|
||||
our $site_name = 'Example.org >> Repos';
|
||||
|
||||
|
||||
The configuration file is used to override the default settings that
|
||||
were built into gitweb at the time the 'gitweb.cgi' script was generated.
|
||||
|
||||
While one could just alter the configuration settings in the gitweb
|
||||
CGI itself, those changes would be lost upon upgrade. Configuration
|
||||
settings might also be placed into a file in the same directory as the
|
||||
CGI script with the default name 'gitweb_config.perl' -- allowing
|
||||
one to have multiple gitweb instances with different configurations by
|
||||
the use of symlinks.
|
||||
|
||||
Note that some configuration can be controlled on per-repository rather than
|
||||
gitweb-wide basis: see "Per-repository gitweb configuration" subsection on
|
||||
linkgit:gitweb[1] manpage.
|
||||
|
||||
|
||||
DISCUSSION
|
||||
----------
|
||||
Gitweb reads configuration data from the following sources in the
|
||||
following order:
|
||||
|
||||
* built-in values (some set during build stage),
|
||||
|
||||
* common system-wide configuration file (defaults to
|
||||
'/etc/gitweb-common.conf'),
|
||||
|
||||
* either per-instance configuration file (defaults to 'gitweb_config.perl'
|
||||
in the same directory as the installed gitweb), or if it does not exists
|
||||
then fallback system-wide configuration file (defaults to '/etc/gitweb.conf').
|
||||
|
||||
Values obtained in later configuration files override values obtained earlier
|
||||
in the above sequence.
|
||||
|
||||
Locations of the common system-wide configuration file, the fallback
|
||||
system-wide configuration file and the per-instance configuration file
|
||||
are defined at compile time using build-time Makefile configuration
|
||||
variables, respectively `GITWEB_CONFIG_COMMON`, `GITWEB_CONFIG_SYSTEM`
|
||||
and `GITWEB_CONFIG`.
|
||||
|
||||
You can also override locations of gitweb configuration files during
|
||||
runtime by setting the following environment variables:
|
||||
`GITWEB_CONFIG_COMMON`, `GITWEB_CONFIG_SYSTEM` and `GITWEB_CONFIG`
|
||||
to a non-empty value.
|
||||
|
||||
|
||||
The syntax of the configuration files is that of Perl, since these files are
|
||||
handled by sourcing them as fragments of Perl code (the language that
|
||||
gitweb itself is written in). Variables are typically set using the
|
||||
`our` qualifier (as in "`our $variable = <value>;`") to avoid syntax
|
||||
errors if a new version of gitweb no longer uses a variable and therefore
|
||||
stops declaring it.
|
||||
|
||||
You can include other configuration file using read_config_file()
|
||||
subroutine. For example, one might want to put gitweb configuration
|
||||
related to access control for viewing repositories via Gitolite (one
|
||||
of git repository management tools) in a separate file, e.g. in
|
||||
'/etc/gitweb-gitolite.conf'. To include it, put
|
||||
|
||||
--------------------------------------------------
|
||||
read_config_file("/etc/gitweb-gitolite.conf");
|
||||
--------------------------------------------------
|
||||
|
||||
somewhere in gitweb configuration file used, e.g. in per-installation
|
||||
gitweb configuration file. Note that read_config_file() checks itself
|
||||
that the file it reads exists, and does nothing if it is not found.
|
||||
It also handles errors in included file.
|
||||
|
||||
|
||||
The default configuration with no configuration file at all may work
|
||||
perfectly well for some installations. Still, a configuration file is
|
||||
useful for customizing or tweaking the behavior of gitweb in many ways, and
|
||||
some optional features will not be present unless explicitly enabled using
|
||||
the configurable `%features` variable (see also "Configuring gitweb
|
||||
features" section below).
|
||||
|
||||
|
||||
CONFIGURATION VARIABLES
|
||||
-----------------------
|
||||
Some configuration variables have their default values (embedded in the CGI
|
||||
script) set during building gitweb -- if that is the case, this fact is put
|
||||
in their description. See gitweb's 'INSTALL' file for instructions on building
|
||||
and installing gitweb.
|
||||
|
||||
|
||||
Location of repositories
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The configuration variables described below control how gitweb finds
|
||||
git repositories, and how repositories are displayed and accessed.
|
||||
|
||||
See also "Repositories" and later subsections in linkgit:gitweb[1] manpage.
|
||||
|
||||
$projectroot::
|
||||
Absolute filesystem path which will be prepended to project path;
|
||||
the path to repository is `$projectroot/$project`. Set to
|
||||
`$GITWEB_PROJECTROOT` during installation. This variable has to be
|
||||
set correctly for gitweb to find repositories.
|
||||
+
|
||||
For example, if `$projectroot` is set to "/srv/git" by putting the following
|
||||
in gitweb config file:
|
||||
+
|
||||
----------------------------------------------------------------------------
|
||||
our $projectroot = "/srv/git";
|
||||
----------------------------------------------------------------------------
|
||||
+
|
||||
then
|
||||
+
|
||||
------------------------------------------------
|
||||
http://git.example.com/gitweb.cgi?p=foo/bar.git
|
||||
------------------------------------------------
|
||||
+
|
||||
and its path_info based equivalent
|
||||
+
|
||||
------------------------------------------------
|
||||
http://git.example.com/gitweb.cgi/foo/bar.git
|
||||
------------------------------------------------
|
||||
+
|
||||
will map to the path '/srv/git/foo/bar.git' on the filesystem.
|
||||
|
||||
$projects_list::
|
||||
Name of a plain text file listing projects, or a name of directory
|
||||
to be scanned for projects.
|
||||
+
|
||||
Project list files should list one project per line, with each line
|
||||
having the following format
|
||||
+
|
||||
-----------------------------------------------------------------------------
|
||||
<URI-encoded filesystem path to repository> SP <URI-encoded repository owner>
|
||||
-----------------------------------------------------------------------------
|
||||
+
|
||||
The default value of this variable is determined by the `GITWEB_LIST`
|
||||
makefile variable at installation time. If this variable is empty, gitweb
|
||||
will fall back to scanning the `$projectroot` directory for repositories.
|
||||
|
||||
$project_maxdepth::
|
||||
If `$projects_list` variable is unset, gitweb will recursively
|
||||
scan filesystem for git repositories. The `$project_maxdepth`
|
||||
is used to limit traversing depth, relative to `$projectroot`
|
||||
(starting point); it means that directories which are further
|
||||
from `$projectroot` than `$project_maxdepth` will be skipped.
|
||||
+
|
||||
It is purely performance optimization, originally intended for MacOS X,
|
||||
where recursive directory traversal is slow. Gitweb follows symbolic
|
||||
links, but it detects cycles, ignoring any duplicate files and directories.
|
||||
+
|
||||
The default value of this variable is determined by the build-time
|
||||
configuration variable `GITWEB_PROJECT_MAXDEPTH`, which defaults to
|
||||
2007.
|
||||
|
||||
$export_ok::
|
||||
Show repository only if this file exists (in repository). Only
|
||||
effective if this variable evaluates to true. Can be set when
|
||||
building gitweb by setting `GITWEB_EXPORT_OK`. This path is
|
||||
relative to `GIT_DIR`. git-daemon[1] uses 'git-daemon-export-ok',
|
||||
unless started with `--export-all`. By default this variable is
|
||||
not set, which means that this feature is turned off.
|
||||
|
||||
$export_auth_hook::
|
||||
Function used to determine which repositories should be shown.
|
||||
This subroutine should take one parameter, the full path to
|
||||
a project, and if it returns true, that project will be included
|
||||
in the projects list and can be accessed through gitweb as long
|
||||
as it fulfills the other requirements described by $export_ok,
|
||||
$projects_list, and $projects_maxdepth. Example:
|
||||
+
|
||||
----------------------------------------------------------------------------
|
||||
our $export_auth_hook = sub { return -e "$_[0]/git-daemon-export-ok"; };
|
||||
----------------------------------------------------------------------------
|
||||
+
|
||||
though the above might be done by using `$export_ok` instead
|
||||
+
|
||||
----------------------------------------------------------------------------
|
||||
our $export_ok = "git-daemon-export-ok";
|
||||
----------------------------------------------------------------------------
|
||||
+
|
||||
If not set (default), it means that this feature is disabled.
|
||||
+
|
||||
See also more involved example in "Controlling access to git repositories"
|
||||
subsection on linkgit:gitweb[1] manpage.
|
||||
|
||||
$strict_export::
|
||||
Only allow viewing of repositories also shown on the overview page.
|
||||
This for example makes `$gitweb_export_ok` file decide if repository is
|
||||
available and not only if it is shown. If `$gitweb_list` points to
|
||||
file with list of project, only those repositories listed would be
|
||||
available for gitweb. Can be set during building gitweb via
|
||||
`GITWEB_STRICT_EXPORT`. By default this variable is not set, which
|
||||
means that you can directly access those repositories that are hidden
|
||||
from projects list page (e.g. the are not listed in the $projects_list
|
||||
file).
|
||||
|
||||
|
||||
Finding files
|
||||
~~~~~~~~~~~~~
|
||||
The following configuration variables tell gitweb where to find files.
|
||||
The values of these variables are paths on the filesystem.
|
||||
|
||||
$GIT::
|
||||
Core git executable to use. By default set to `$GIT_BINDIR/git`, which
|
||||
in turn is by default set to `$(bindir)/git`. If you use git installed
|
||||
from a binary package, you should usually set this to "/usr/bin/git".
|
||||
This can just be "git" if your web server has a sensible PATH; from
|
||||
security point of view it is better to use absolute path to git binary.
|
||||
If you have multiple git versions installed it can be used to choose
|
||||
which one to use. Must be (correctly) set for gitweb to be able to
|
||||
work.
|
||||
|
||||
$mimetypes_file::
|
||||
File to use for (filename extension based) guessing of MIME types before
|
||||
trying '/etc/mime.types'. *NOTE* that this path, if relative, is taken
|
||||
as relative to the current git repository, not to CGI script. If unset,
|
||||
only '/etc/mime.types' is used (if present on filesystem). If no mimetypes
|
||||
file is found, mimetype guessing based on extension of file is disabled.
|
||||
Unset by default.
|
||||
|
||||
$highlight_bin::
|
||||
Path to the highlight executable to use (it must be the one from
|
||||
http://www.andre-simon.de[] due to assumptions about parameters and output).
|
||||
By default set to 'highlight'; set it to full path to highlight
|
||||
executable if it is not installed on your web server's PATH.
|
||||
Note that 'highlight' feature must be set for gitweb to actually
|
||||
use syntax hightlighting.
|
||||
+
|
||||
*NOTE*: if you want to add support for new file type (supported by
|
||||
"highlight" but not used by gitweb), you need to modify `%highlight_ext`
|
||||
or `%highlight_basename`, depending on whether you detect type of file
|
||||
based on extension (for example "sh") or on its basename (for example
|
||||
"Makefile"). The keys of these hashes are extension and basename,
|
||||
respectively, and value for given key is name of syntax to be passed via
|
||||
`--syntax <syntax>` to highlighter.
|
||||
+
|
||||
For example if repositories you are hosting use "phtml" extension for
|
||||
PHP files, and you want to have correct syntax-highlighting for those
|
||||
files, you can add the following to gitweb configuration:
|
||||
+
|
||||
---------------------------------------------------------
|
||||
our %highlight_ext;
|
||||
$highlight_ext{'phtml'} = 'php';
|
||||
---------------------------------------------------------
|
||||
|
||||
|
||||
Links and their targets
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The configuration variables described below configure some of gitweb links:
|
||||
their target and their look (text or image), and where to find page
|
||||
prerequisites (stylesheet, favicon, images, scripts). Usually they are left
|
||||
at their default values, with the possible exception of `@stylesheets`
|
||||
variable.
|
||||
|
||||
@stylesheets::
|
||||
List of URIs of stylesheets (relative to the base URI of a page). You
|
||||
might specify more than one stylesheet, for example to use "gitweb.css"
|
||||
as base with site specific modifications in a separate stylesheet
|
||||
to make it easier to upgrade gitweb. For example, you can add
|
||||
a `site` stylesheet by putting
|
||||
+
|
||||
----------------------------------------------------------------------------
|
||||
push @stylesheets, "gitweb-site.css";
|
||||
----------------------------------------------------------------------------
|
||||
+
|
||||
in the gitweb config file. Those values that are relative paths are
|
||||
relative to base URI of gitweb.
|
||||
+
|
||||
This list should contain the URI of gitweb's standard stylesheet. The default
|
||||
URI of gitweb stylesheet can be set at build time using the `GITWEB_CSS`
|
||||
makefile variable. Its default value is 'static/gitweb.css'
|
||||
(or 'static/gitweb.min.css' if the `CSSMIN` variable is defined,
|
||||
i.e. if CSS minifier is used during build).
|
||||
+
|
||||
*Note*: there is also a legacy `$stylesheet` configuration variable, which was
|
||||
used by older gitweb. If `$stylesheet` variable is defined, only CSS stylesheet
|
||||
given by this variable is used by gitweb.
|
||||
|
||||
$logo::
|
||||
Points to the location where you put 'git-logo.png' on your web
|
||||
server, or to be more the generic URI of logo, 72x27 size). This image
|
||||
is displayed in the top right corner of each gitweb page and used as
|
||||
a logo for the Atom feed. Relative to the base URI of gitweb (as a path).
|
||||
Can be adjusted when building gitweb using `GITWEB_LOGO` variable
|
||||
By default set to 'static/git-logo.png'.
|
||||
|
||||
$favicon::
|
||||
Points to the location where you put 'git-favicon.png' on your web
|
||||
server, or to be more the generic URI of favicon, which will be served
|
||||
as "image/png" type. Web browsers that support favicons (website icons)
|
||||
may display them in the browser's URL bar and next to the site name in
|
||||
bookmarks. Relative to the base URI of gitweb. Can be adjusted at
|
||||
build time using `GITWEB_FAVICON` variable.
|
||||
By default set to 'static/git-favicon.png'.
|
||||
|
||||
$javascript::
|
||||
Points to the location where you put 'gitweb.js' on your web server,
|
||||
or to be more generic the URI of JavaScript code used by gitweb.
|
||||
Relative to the base URI of gitweb. Can be set at build time using
|
||||
the `GITWEB_JS` build-time configuration variable.
|
||||
+
|
||||
The default value is either 'static/gitweb.js', or 'static/gitweb.min.js' if
|
||||
the `JSMIN` build variable was defined, i.e. if JavaScript minifier was used
|
||||
at build time. *Note* that this single file is generated from multiple
|
||||
individual JavaScript "modules".
|
||||
|
||||
$home_link::
|
||||
Target of the home link on the top of all pages (the first part of view
|
||||
"breadcrumbs"). By default it is set to the absolute URI of a current page
|
||||
(to the value of `$my_uri` variable, or to "/" if `$my_uri` is undefined
|
||||
or is an empty string).
|
||||
|
||||
$home_link_str::
|
||||
Label for the "home link" at the top of all pages, leading to `$home_link`
|
||||
(usually the main gitweb page, which contains the projects list). It is
|
||||
used as the first component of gitweb's "breadcrumb trail":
|
||||
`<home link> / <project> / <action>`. Can be set at build time using
|
||||
the `GITWEB_HOME_LINK_STR` variable. By default it is set to "projects",
|
||||
as this link leads to the list of projects. Other popular choice it to
|
||||
set it to the name of site.
|
||||
|
||||
$logo_url::
|
||||
$logo_label::
|
||||
URI and label (title) for the Git logo link (or your site logo,
|
||||
if you chose to use different logo image). By default, these both
|
||||
refer to git homepage, http://git-scm.com[]; in the past, they pointed
|
||||
to git documentation at http://www.kernel.org[].
|
||||
|
||||
|
||||
Changing gitweb's look
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
You can adjust how pages generated by gitweb look using the variables described
|
||||
below. You can change the site name, add common headers and footers for all
|
||||
pages, and add a description of this gitweb installation on its main page
|
||||
(which is the projects list page), etc.
|
||||
|
||||
$site_name::
|
||||
Name of your site or organization, to appear in page titles. Set it
|
||||
to something descriptive for clearer bookmarks etc. If this variable
|
||||
is not set or is, then gitweb uses the value of the `SERVER_NAME`
|
||||
CGI environment variable, setting site name to "$SERVER_NAME Git",
|
||||
or "Untitled Git" if this variable is not set (e.g. if running gitweb
|
||||
as standalone script).
|
||||
+
|
||||
Can be set using the `GITWEB_SITENAME` at build time. Unset by default.
|
||||
|
||||
$site_html_head_string::
|
||||
HTML snippet to be included in the <head> section of each page.
|
||||
Can be set using `GITWEB_SITE_HTML_HEAD_STRING` at build time.
|
||||
No default value.
|
||||
|
||||
$site_header::
|
||||
Name of a file with HTML to be included at the top of each page.
|
||||
Relative to the directory containing the 'gitweb.cgi' script.
|
||||
Can be set using `GITWEB_SITE_HEADER` at build time. No default
|
||||
value.
|
||||
|
||||
$site_footer::
|
||||
Name of a file with HTML to be included at the bottom of each page.
|
||||
Relative to the directory containing the 'gitweb.cgi' script.
|
||||
Can be set using `GITWEB_SITE_FOOTER` at build time. No default
|
||||
value.
|
||||
|
||||
$home_text::
|
||||
Name of a HTML file which, if it exists, is included on the
|
||||
gitweb projects overview page ("projects_list" view). Relative to
|
||||
the directory containing the gitweb.cgi script. Default value
|
||||
can be adjusted during build time using `GITWEB_HOMETEXT` variable.
|
||||
By default set to 'indextext.html'.
|
||||
|
||||
$projects_list_description_width::
|
||||
The width (in characters) of the "Description" column of the projects list.
|
||||
Longer descriptions will be truncated (trying to cut at word boundary);
|
||||
the full description is available in the 'title' attribute (usually shown on
|
||||
mouseover). The default is 25, which might be too small if you
|
||||
use long project descriptions.
|
||||
|
||||
$default_projects_order::
|
||||
Default value of ordering of projects on projects list page, which
|
||||
means the ordering used if you don't explicitly sort projects list
|
||||
(if there is no "o" CGI query parameter in the URL). Valid values
|
||||
are "none" (unsorted), "project" (projects are by project name,
|
||||
i.e. path to repository relative to `$projectroot`), "descr"
|
||||
(project description), "owner", and "age" (by date of most current
|
||||
commit).
|
||||
+
|
||||
Default value is "project". Unknown value means unsorted.
|
||||
|
||||
|
||||
Changing gitweb's behavior
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
These configuration variables control _internal_ gitweb behavior.
|
||||
|
||||
$default_blob_plain_mimetype::
|
||||
Default mimetype for the blob_plain (raw) view, if mimetype checking
|
||||
doesn't result in some other type; by default "text/plain".
|
||||
Gitweb guesses mimetype of a file to display based on extension
|
||||
of its filename, using `$mimetypes_file` (if set and file exists)
|
||||
and '/etc/mime.types' files (see *mime.types*(5) manpage; only
|
||||
filename extension rules are supported by gitweb).
|
||||
|
||||
$default_text_plain_charset::
|
||||
Default charset for text files. If this is not set, the web server
|
||||
configuration will be used. Unset by default.
|
||||
|
||||
$fallback_encoding::
|
||||
Gitweb assumes this charset when a line contains non-UTF-8 characters.
|
||||
The fallback decoding is used without error checking, so it can be even
|
||||
"utf-8". The value must be a valid encoding; see the *Encoding::Supported*(3pm)
|
||||
man page for a list. The default is "latin1", aka. "iso-8859-1".
|
||||
|
||||
@diff_opts::
|
||||
Rename detection options for git-diff and git-diff-tree. The default is
|
||||
(\'-M'); set it to (\'-C') or (\'-C', \'-C') to also detect copies,
|
||||
or set it to () i.e. empty list if you don't want to have renames
|
||||
detection.
|
||||
+
|
||||
*Note* that rename and especially copy detection can be quite
|
||||
CPU-intensive. Note also that non git tools can have problems with
|
||||
patches generated with options mentioned above, especially when they
|
||||
involve file copies (\'-C') or criss-cross renames (\'-B').
|
||||
|
||||
|
||||
Some optional features and policies
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Most of features are configured via `%feature` hash; however some of extra
|
||||
gitweb features can be turned on and configured using variables described
|
||||
below. This list beside configuration variables that control how gitweb
|
||||
looks does contain variables configuring administrative side of gitweb
|
||||
(e.g. cross-site scripting prevention; admittedly this as side effect
|
||||
affects how "summary" pages look like, or load limiting).
|
||||
|
||||
@git_base_url_list::
|
||||
List of git base URLs. These URLs are used to generate URLs
|
||||
describing from where to fetch a project, which are shown on
|
||||
project summary page. The full fetch URL is "`$git_base_url/$project`",
|
||||
for each element of this list. You can set up multiple base URLs
|
||||
(for example one for `git://` protocol, and one for `http://`
|
||||
protocol).
|
||||
+
|
||||
Note that per repository configuration can be set in '$GIT_DIR/cloneurl'
|
||||
file, or as values of multi-value `gitweb.url` configuration variable in
|
||||
project config. Per-repository configuration takes precedence over value
|
||||
composed from `@git_base_url_list` elements and project name.
|
||||
+
|
||||
You can setup one single value (single entry/item in this list) at build
|
||||
time by setting the `GITWEB_BASE_URL` built-time configuration variable.
|
||||
By default it is set to (), i.e. an empty list. This means that gitweb
|
||||
would not try to create project URL (to fetch) from project name.
|
||||
|
||||
$projects_list_group_categories::
|
||||
Whether to enables the grouping of projects by category on the project
|
||||
list page. The category of a project is determined by the
|
||||
`$GIT_DIR/category` file or the `gitweb.category` variable in each
|
||||
repository's configuration. Disabled by default (set to 0).
|
||||
|
||||
$project_list_default_category::
|
||||
Default category for projects for which none is specified. If this is
|
||||
set to the empty string, such projects will remain uncategorized and
|
||||
listed at the top, above categorized projects. Used only if project
|
||||
categories are enabled, which means if `$projects_list_group_categories`
|
||||
is true. By default set to "" (empty string).
|
||||
|
||||
$prevent_xss::
|
||||
If true, some gitweb features are disabled to prevent content in
|
||||
repositories from launching cross-site scripting (XSS) attacks. Set this
|
||||
to true if you don't trust the content of your repositories.
|
||||
False by default (set to 0).
|
||||
|
||||
$maxload::
|
||||
Used to set the maximum load that we will still respond to gitweb queries.
|
||||
If the server load exceeds this value then gitweb will return
|
||||
"503 Service Unavailable" error. The server load is taken to be 0
|
||||
if gitweb cannot determine its value. Currently it works only on Linux,
|
||||
where it uses '/proc/loadavg'; the load there is the number of active
|
||||
tasks on the system -- processes that are actually running -- averaged
|
||||
over the last minute.
|
||||
+
|
||||
Set `$maxload` to undefined value (`undef`) to turn this feature off.
|
||||
The default value is 300.
|
||||
|
||||
$per_request_config::
|
||||
If this is set to code reference, it will be run once for each request.
|
||||
You can set parts of configuration that change per session this way.
|
||||
For example, one might use the following code in a gitweb configuration
|
||||
file
|
||||
+
|
||||
--------------------------------------------------------------------------------
|
||||
our $per_request_config = sub {
|
||||
$ENV{GL_USER} = $cgi->remote_user || "gitweb";
|
||||
};
|
||||
--------------------------------------------------------------------------------
|
||||
+
|
||||
If `$per_request_config` is not a code reference, it is interpreted as boolean
|
||||
value. If it is true gitweb will process config files once per request,
|
||||
and if it is false gitweb will process config files only once, each time it
|
||||
is executed. True by default (set to 1).
|
||||
+
|
||||
*NOTE*: `$my_url`, `$my_uri`, and `$base_url` are overwritten with their default
|
||||
values before every request, so if you want to change them, be sure to set
|
||||
this variable to true or a code reference effecting the desired changes.
|
||||
+
|
||||
This variable matters only when using persistent web environments that
|
||||
serve multiple requests using single gitweb instance, like mod_perl,
|
||||
FastCGI or Plackup.
|
||||
|
||||
|
||||
Other variables
|
||||
~~~~~~~~~~~~~~~
|
||||
Usually you should not need to change (adjust) any of configuration
|
||||
variables described below; they should be automatically set by gitweb to
|
||||
correct value.
|
||||
|
||||
|
||||
$version::
|
||||
Gitweb version, set automatically when creating gitweb.cgi from
|
||||
gitweb.perl. You might want to modify it if you are running modified
|
||||
gitweb, for example
|
||||
+
|
||||
---------------------------------------------------
|
||||
our $version .= " with caching";
|
||||
---------------------------------------------------
|
||||
+
|
||||
if you run modified version of gitweb with caching support. This variable
|
||||
is purely informational, used e.g. in the "generator" meta header in HTML
|
||||
header.
|
||||
|
||||
$my_url::
|
||||
$my_uri::
|
||||
Full URL and absolute URL of the gitweb script;
|
||||
in earlier versions of gitweb you might have need to set those
|
||||
variables, but now there should be no need to do it. See
|
||||
`$per_request_config` if you need to set them still.
|
||||
|
||||
$base_url::
|
||||
Base URL for relative URLs in pages generated by gitweb,
|
||||
(e.g. `$logo`, `$favicon`, `@stylesheets` if they are relative URLs),
|
||||
needed and used '<base href="$base_url">' only for URLs with nonempty
|
||||
PATH_INFO. Usually gitweb sets its value correctly,
|
||||
and there is no need to set this variable, e.g. to $my_uri or "/".
|
||||
See `$per_request_config` if you need to override it anyway.
|
||||
|
||||
|
||||
CONFIGURING GITWEB FEATURES
|
||||
---------------------------
|
||||
Many gitweb features can be enabled (or disabled) and configured using the
|
||||
`%feature` hash. Names of gitweb features are keys of this hash.
|
||||
|
||||
Each `%feature` hash element is a hash reference and has the following
|
||||
structure:
|
||||
----------------------------------------------------------------------
|
||||
"<feature_name>" => {
|
||||
"sub" => <feature-sub (subroutine)>,
|
||||
"override" => <allow-override (boolean)>,
|
||||
"default" => [ <options>... ]
|
||||
},
|
||||
----------------------------------------------------------------------
|
||||
Some features cannot be overridden per project. For those
|
||||
features the structure of appropriate `%feature` hash element has a simpler
|
||||
form:
|
||||
----------------------------------------------------------------------
|
||||
"<feature_name>" => {
|
||||
"override" => 0,
|
||||
"default" => [ <options>... ]
|
||||
},
|
||||
----------------------------------------------------------------------
|
||||
As one can see it lacks the \'sub' element.
|
||||
|
||||
The meaning of each part of feature configuration is described
|
||||
below:
|
||||
|
||||
default::
|
||||
List (array reference) of feature parameters (if there are any),
|
||||
used also to toggle (enable or disable) given feature.
|
||||
+
|
||||
Note that it is currently *always* an array reference, even if
|
||||
feature doesn't accept any configuration parameters, and \'default'
|
||||
is used only to turn it on or off. In such case you turn feature on
|
||||
by setting this element to `[1]`, and torn it off by setting it to
|
||||
`[0]`. See also the passage about the "blame" feature in the "Examples"
|
||||
section.
|
||||
+
|
||||
To disable features that accept parameters (are configurable), you
|
||||
need to set this element to empty list i.e. `[]`.
|
||||
|
||||
override::
|
||||
If this field has a true value then the given feature is
|
||||
overriddable, which means that it can be configured
|
||||
(or enabled/disabled) on a per-repository basis.
|
||||
+
|
||||
Usually given "<feature>" is configurable via the `gitweb.<feature>`
|
||||
config variable in the per-repository git configuration file.
|
||||
+
|
||||
*Note* that no feature is overriddable by default.
|
||||
|
||||
sub::
|
||||
Internal detail of implementation. What is important is that
|
||||
if this field is not present then per-repository override for
|
||||
given feature is not supported.
|
||||
+
|
||||
You wouldn't need to ever change it in gitweb config file.
|
||||
|
||||
|
||||
Features in `%feature`
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
The gitweb features that are configurable via `%feature` hash are listed
|
||||
below. This should be a complete list, but ultimately the authoritative
|
||||
and complete list is in gitweb.cgi source code, with features described
|
||||
in the comments.
|
||||
|
||||
blame::
|
||||
Enable the "blame" and "blame_incremental" blob views, showing for
|
||||
each line the last commit that modified it; see linkgit:git-blame[1].
|
||||
This can be very CPU-intensive and is therefore disabled by default.
|
||||
+
|
||||
This feature can be configured on a per-repository basis via
|
||||
repository's `gitweb.blame` configuration variable (boolean).
|
||||
|
||||
snapshot::
|
||||
Enable and configure the "snapshot" action, which allows user to
|
||||
download a compressed archive of any tree or commit, as produced
|
||||
by linkgit:git-archive[1] and possibly additionally compressed.
|
||||
This can potentially generate high traffic if you have large project.
|
||||
+
|
||||
The value of \'default' is a list of names of snapshot formats,
|
||||
defined in `%known_snapshot_formats` hash, that you wish to offer.
|
||||
Supported formats include "tgz", "tbz2", "txz" (gzip/bzip2/xz
|
||||
compressed tar archive) and "zip"; please consult gitweb sources for
|
||||
a definitive list. By default only "tgz" is offered.
|
||||
+
|
||||
This feature can be configured on a per-repository basis via
|
||||
repository's `gitweb.blame` configuration variable, which contains
|
||||
a comma separated list of formats or "none" to disable snapshots.
|
||||
Unknown values are ignored.
|
||||
|
||||
grep::
|
||||
Enable grep search, which lists the files in currently selected
|
||||
tree (directory) containing the given string; see linkgit:git-grep[1].
|
||||
This can be potentially CPU-intensive, of course. Enabled by default.
|
||||
+
|
||||
This feature can be configured on a per-repository basis via
|
||||
repository's `gitweb.grep` configuration variable (boolean).
|
||||
|
||||
pickaxe::
|
||||
Enable the so called pickaxe search, which will list the commits
|
||||
that introduced or removed a given string in a file. This can be
|
||||
practical and quite faster alternative to "blame" action, but it is
|
||||
still potentially CPU-intensive. Enabled by default.
|
||||
+
|
||||
The pickaxe search is described in linkgit:git-log[1] (the
|
||||
description of `-S<string>` option, which refers to pickaxe entry in
|
||||
linkgit:gitdiffcore[7] for more details).
|
||||
+
|
||||
This feature can be configured on a per-repository basis by setting
|
||||
repository's `gitweb.pickaxe` configuration variable (boolean).
|
||||
|
||||
show-sizes::
|
||||
Enable showing size of blobs (ordinary files) in a "tree" view, in a
|
||||
separate column, similar to what `ls -l` does; see description of
|
||||
`-l` option in linkgit:git-ls-tree[1] manpage. This costs a bit of
|
||||
I/O. Enabled by default.
|
||||
+
|
||||
This feature can be configured on a per-repository basis via
|
||||
repository's `gitweb.showsizes` configuration variable (boolean).
|
||||
|
||||
patches::
|
||||
Enable and configure "patches" view, which displays list of commits in email
|
||||
(plain text) output format; see also linkgit:git-format-patch[1].
|
||||
The value is the maximum number of patches in a patchset generated
|
||||
in "patches" view. Set the 'default' field to a list containing single
|
||||
item of or to an empty list to disable patch view, or to a list
|
||||
containing a single negative number to remove any limit.
|
||||
Default value is 16.
|
||||
+
|
||||
This feature can be configured on a per-repository basis via
|
||||
repository's `gitweb.patches` configuration variable (integer).
|
||||
|
||||
avatar::
|
||||
Avatar support. When this feature is enabled, views such as
|
||||
"shortlog" or "commit" will display an avatar associated with
|
||||
the email of each committer and author.
|
||||
+
|
||||
Currently available providers are *"gravatar"* and *"picon"*.
|
||||
Only one provider at a time can be selected ('default' is one element list).
|
||||
If an unknown provider is specified, the feature is disabled.
|
||||
*Note* that some providers might require extra Perl packages to be
|
||||
installed; see 'gitweb/INSTALL' for more details.
|
||||
+
|
||||
This feature can be configured on a per-repository basis via
|
||||
repository's `gitweb.avatar` configuration variable.
|
||||
+
|
||||
See also `%avatar_size` with pixel sizes for icons and avatars
|
||||
("default" is used for one-line like "log" and "shortlog", "double"
|
||||
is used for two-line like "commit", "commitdiff" or "tag"). If the
|
||||
default font sizes or lineheights are changed (e.g. via adding extra
|
||||
CSS stylesheet in `@stylesheets`), it may be appropriate to change
|
||||
these values.
|
||||
|
||||
highlight::
|
||||
Server-side syntax highlight support in "blob" view. It requires
|
||||
`$highlight_bin` program to be available (see the description of
|
||||
this variable in the "Configuration variables" section above),
|
||||
and therefore is disabled by default.
|
||||
+
|
||||
This feature can be configured on a per-repository basis via
|
||||
repository's `gitweb.highlight` configuration variable (boolean).
|
||||
|
||||
remote_heads::
|
||||
Enable displaying remote heads (remote-tracking branches) in the "heads"
|
||||
list. In most cases the list of remote-tracking branches is an
|
||||
unnecessary internal private detail, and this feature is therefore
|
||||
disabled by default. linkgit:git-instaweb[1], which is usually used
|
||||
to browse local repositories, enables and uses this feature.
|
||||
+
|
||||
This feature can be configured on a per-repository basis via
|
||||
repository's `gitweb.remote_heads` configuration variable (boolean).
|
||||
|
||||
|
||||
The remaining features cannot be overridden on a per project basis.
|
||||
|
||||
search::
|
||||
Enable text search, which will list the commits which match author,
|
||||
committer or commit text to a given string; see the description of
|
||||
`--author`, `--committer` and `--grep` options in linkgit:git-log[1]
|
||||
manpage. Enabled by default.
|
||||
+
|
||||
Project specific override is not supported.
|
||||
|
||||
forks::
|
||||
If this feature is enabled, gitweb considers projects in
|
||||
subdirectories of project root (basename) to be forks of existing
|
||||
projects. For each project `$projname.git`, projects in the
|
||||
`$projname/` directory and its subdirectories will not be
|
||||
shown in the main projects list. Instead, a \'+' mark is shown
|
||||
next to `$projname`, which links to a "forks" view that lists all
|
||||
the forks (all projects in `$projname/` subdirectory). Additionally
|
||||
a "forks" view for a project is linked from project summary page.
|
||||
+
|
||||
If the project list is taken from a file (`$projects_list` points to a
|
||||
file), forks are only recognized if they are listed after the main project
|
||||
in that file.
|
||||
+
|
||||
Project specific override is not supported.
|
||||
|
||||
actions::
|
||||
Insert custom links to the action bar of all project pages. This
|
||||
allows you to link to third-party scripts integrating into gitweb.
|
||||
+
|
||||
The "default" value consists of a list of triplets in the form
|
||||
`("<label>", "<link>", "<position>")` where "position" is the label
|
||||
after which to insert the link, "link" is a format string where `%n`
|
||||
expands to the project name, `%f` to the project path within the
|
||||
filesystem (i.e. "$projectroot/$project"), `%h` to the current hash
|
||||
(\'h' gitweb parameter) and `%b` to the current hash base
|
||||
(\'hb' gitweb parameter); `%%` expands to \'%'.
|
||||
+
|
||||
For example, at the time this page was written, the http://repo.or.cz[]
|
||||
git hosting site set it to the following to enable graphical log
|
||||
(using the third party tool *git-browser*):
|
||||
+
|
||||
----------------------------------------------------------------------
|
||||
$feature{'actions'}{'default'} =
|
||||
[ ('graphiclog', '/git-browser/by-commit.html?r=%n', 'summary')];
|
||||
----------------------------------------------------------------------
|
||||
+
|
||||
This adds a link titled "graphiclog" after the "summary" link, leading to
|
||||
`git-browser` script, passing `r=<project>` as a query parameter.
|
||||
+
|
||||
Project specific override is not supported.
|
||||
|
||||
timed::
|
||||
Enable displaying how much time and how many git commands it took to
|
||||
generate and display each page in the page footer (at the bottom of
|
||||
page). For example the footer might contain: "This page took 6.53325
|
||||
seconds and 13 git commands to generate." Disabled by default.
|
||||
+
|
||||
Project specific override is not supported.
|
||||
|
||||
javascript-timezone::
|
||||
Enable and configure the ability to change a common timezone for dates
|
||||
in gitweb output via JavaScript. Dates in gitweb output include
|
||||
authordate and committerdate in "commit", "commitdiff" and "log"
|
||||
views, and taggerdate in "tag" view. Enabled by default.
|
||||
+
|
||||
The value is a list of three values: a default timezone (for if the client
|
||||
hasn't selected some other timezone and saved it in a cookie), a name of cookie
|
||||
where to store selected timezone, and a CSS class used to mark up
|
||||
dates for manipulation. If you want to turn this feature off, set "default"
|
||||
to empty list: `[]`.
|
||||
+
|
||||
Typical gitweb config files will only change starting (default) timezone,
|
||||
and leave other elements at their default values:
|
||||
+
|
||||
---------------------------------------------------------------------------
|
||||
$feature{'javascript-timezone'}{'default'}[0] = "utc";
|
||||
---------------------------------------------------------------------------
|
||||
+
|
||||
The example configuration presented here is guaranteed to be backwards
|
||||
and forward compatible.
|
||||
+
|
||||
Timezone values can be "local" (for local timezone that browser uses), "utc"
|
||||
(what gitweb uses when JavaScript or this feature is disabled), or numerical
|
||||
timezones in the form of "+/-HHMM", such as "+0200".
|
||||
+
|
||||
Project specific override is not supported.
|
||||
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
|
||||
To enable blame, pickaxe search, and snapshot support (allowing "tar.gz" and
|
||||
"zip" snapshots), while allowing individual projects to turn them off, put
|
||||
the following in your GITWEB_CONFIG file:
|
||||
|
||||
$feature{'blame'}{'default'} = [1];
|
||||
$feature{'blame'}{'override'} = 1;
|
||||
|
||||
$feature{'pickaxe'}{'default'} = [1];
|
||||
$feature{'pickaxe'}{'override'} = 1;
|
||||
|
||||
$feature{'snapshot'}{'default'} = ['zip', 'tgz'];
|
||||
$feature{'snapshot'}{'override'} = 1;
|
||||
|
||||
If you allow overriding for the snapshot feature, you can specify which
|
||||
snapshot formats are globally disabled. You can also add any command line
|
||||
options you want (such as setting the compression level). For instance, you
|
||||
can disable Zip compressed snapshots and set *gzip*(1) to run at level 6 by
|
||||
adding the following lines to your gitweb configuration file:
|
||||
|
||||
$known_snapshot_formats{'zip'}{'disabled'} = 1;
|
||||
$known_snapshot_formats{'tgz'}{'compressor'} = ['gzip','-6'];
|
||||
|
||||
ENVIRONMENT
|
||||
-----------
|
||||
The location of per-instance and system-wide configuration files can be
|
||||
overridden using the following environment variables:
|
||||
|
||||
GITWEB_CONFIG::
|
||||
Sets location of per-instance configuration file.
|
||||
GITWEB_CONFIG_SYSTEM::
|
||||
Sets location of fallback system-wide configuration file.
|
||||
This file is read only if per-instance one does not exist.
|
||||
GITWEB_CONFIG_COMMON::
|
||||
Sets location of common system-wide configuration file.
|
||||
|
||||
|
||||
FILES
|
||||
-----
|
||||
gitweb_config.perl::
|
||||
This is default name of per-instance configuration file. The
|
||||
format of this file is described above.
|
||||
/etc/gitweb.conf::
|
||||
This is default name of fallback system-wide configuration
|
||||
file. This file is used only if per-instance configuration
|
||||
variable is not found.
|
||||
/etc/gitweb-common.conf::
|
||||
This is default name of common system-wide configuration
|
||||
file.
|
||||
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
linkgit:gitweb[1], linkgit:git-instaweb[1]
|
||||
|
||||
'gitweb/README', 'gitweb/INSTALL'
|
||||
|
||||
GIT
|
||||
---
|
||||
Part of the linkgit:git[1] suite
|
@ -1,704 +0,0 @@
|
||||
gitweb(1)
|
||||
=========
|
||||
|
||||
NAME
|
||||
----
|
||||
gitweb - Git web interface (web frontend to Git repositories)
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
To get started with gitweb, run linkgit:git-instaweb[1] from a git repository.
|
||||
This would configure and start your web server, and run web browser pointing to
|
||||
gitweb.
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
Gitweb provides a web interface to git repositories. It's features include:
|
||||
|
||||
* Viewing multiple Git repositories with common root.
|
||||
* Browsing every revision of the repository.
|
||||
* Viewing the contents of files in the repository at any revision.
|
||||
* Viewing the revision log of branches, history of files and directories,
|
||||
see what was changed when, by who.
|
||||
* Viewing the blame/annotation details of any file (if enabled).
|
||||
* Generating RSS and Atom feeds of commits, for any branch.
|
||||
The feeds are auto-discoverable in modern web browsers.
|
||||
* Viewing everything that was changed in a revision, and step through
|
||||
revisions one at a time, viewing the history of the repository.
|
||||
* Finding commits which commit messages matches given search term.
|
||||
|
||||
See http://git.kernel.org/?p=git/git.git;a=tree;f=gitweb[] or
|
||||
http://repo.or.cz/w/git.git/tree/HEAD:/gitweb/[] for gitweb source code,
|
||||
browsed using gitweb itself.
|
||||
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
Various aspects of gitweb's behavior can be controlled through the configuration
|
||||
file 'gitweb_config.perl' or '/etc/gitweb.conf'. See the linkgit:gitweb.conf[5]
|
||||
for details.
|
||||
|
||||
Repositories
|
||||
~~~~~~~~~~~~
|
||||
Gitweb can show information from one or more Git repositories. These
|
||||
repositories have to be all on local filesystem, and have to share common
|
||||
repository root, i.e. be all under a single parent repository (but see also
|
||||
"Advanced web server setup" section, "Webserver configuration with multiple
|
||||
projects' root" subsection).
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
our $projectroot = '/path/to/parent/directory';
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
The default value for `$projectroot` is '/pub/git'. You can change it during
|
||||
building gitweb via `GITWEB_PROJECTROOT` build configuration variable.
|
||||
|
||||
By default all git repositories under `$projectroot` are visible and available
|
||||
to gitweb. The list of projects is generated by default by scanning the
|
||||
`$projectroot` directory for git repositories (for object databases to be
|
||||
more exact; gitweb is not interested in a working area, and is best suited
|
||||
to showing "bare" repositories).
|
||||
|
||||
The name of repository in gitweb is path to it's `$GIT_DIR` (it's object
|
||||
database) relative to `$projectroot`. Therefore the repository $repo can be
|
||||
found at "$projectroot/$repo".
|
||||
|
||||
|
||||
Projects list file format
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Instead of having gitweb find repositories by scanning filesystem
|
||||
starting from $projectroot, you can provide a pre-generated list of
|
||||
visible projects by setting `$projects_list` to point to a plain text
|
||||
file with a list of projects (with some additional info).
|
||||
|
||||
This file uses the following format:
|
||||
|
||||
* One record (for project / repository) per line; does not support line
|
||||
continuation (newline escaping).
|
||||
|
||||
* Leading and trailing whitespace are ignored.
|
||||
|
||||
* Whitespace separated fields; any run of whitespace can be used as field
|
||||
separator (rules for Perl's "`split(" ", $line)`").
|
||||
|
||||
* Fields use modified URI encoding, defined in RFC 3986, section 2.1
|
||||
(Percent-Encoding), or rather "Query string encoding" (see
|
||||
link:http://en.wikipedia.org/wiki/Query_string#URL_encoding[]), the difference
|
||||
being that SP (" ") can be encoded as "{plus}" (and therefore "{plus}" has to be
|
||||
also percent-encoded).
|
||||
+
|
||||
Reserved characters are: "%" (used for encoding), "{plus}" (can be used to
|
||||
encode SPACE), all whitespace characters as defined in Perl, including SP,
|
||||
TAB and LF, (used to separate fields in a record).
|
||||
|
||||
* Currently recognized fields are:
|
||||
<repository path>::
|
||||
path to repository GIT_DIR, relative to `$projectroot`
|
||||
<repository owner>::
|
||||
displayed as repository owner, preferably full name, or email,
|
||||
or both
|
||||
|
||||
You can generate the projects list index file using the project_index action
|
||||
(the 'TXT' link on projects list page) directly from gitweb; see also
|
||||
"Generating projects list using gitweb" section below.
|
||||
|
||||
Example contents:
|
||||
-----------------------------------------------------------------------
|
||||
foo.git Joe+R+Hacker+<joe@example.com>
|
||||
foo/bar.git O+W+Ner+<owner@example.org>
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
|
||||
By default this file controls only which projects are *visible* on projects
|
||||
list page (note that entries that do not point to correctly recognized git
|
||||
repositories won't be displayed by gitweb). Even if a project is not
|
||||
visible on projects list page, you can view it nevertheless by hand-crafting
|
||||
a gitweb URL. By setting `$strict_export` configuration variable (see
|
||||
linkgit:gitweb.conf[5]) to true value you can allow viewing only of
|
||||
repositories also shown on the overview page (i.e. only projects explicitly
|
||||
listed in projects list file will be accessible).
|
||||
|
||||
|
||||
Generating projects list using gitweb
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
We assume that GITWEB_CONFIG has its default Makefile value, namely
|
||||
'gitweb_config.perl'. Put the following in 'gitweb_make_index.perl' file:
|
||||
----------------------------------------------------------------------------
|
||||
read_config_file("gitweb_config.perl");
|
||||
$projects_list = $projectroot;
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
Then create the following script to get list of project in the format
|
||||
suitable for GITWEB_LIST build configuration variable (or
|
||||
`$projects_list` variable in gitweb config):
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
#!/bin/sh
|
||||
|
||||
export GITWEB_CONFIG="gitweb_make_index.perl"
|
||||
export GATEWAY_INTERFACE="CGI/1.1"
|
||||
export HTTP_ACCEPT="*/*"
|
||||
export REQUEST_METHOD="GET"
|
||||
export QUERY_STRING="a=project_index"
|
||||
|
||||
perl -- /var/www/cgi-bin/gitweb.cgi
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
Run this script and save its output to a file. This file could then be used
|
||||
as projects list file, which means that you can set `$projects_list` to its
|
||||
filename.
|
||||
|
||||
|
||||
Controlling access to git repositories
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
By default all git repositories under `$projectroot` are visible and
|
||||
available to gitweb. You can however configure how gitweb controls access
|
||||
to repositories.
|
||||
|
||||
* As described in "Projects list file format" section, you can control which
|
||||
projects are *visible* by selectively including repositories in projects
|
||||
list file, and setting `$projects_list` gitweb configuration variable to
|
||||
point to it. With `$strict_export` set, projects list file can be used to
|
||||
control which repositories are *available* as well.
|
||||
|
||||
* You can configure gitweb to only list and allow viewing of the explicitly
|
||||
exported repositories, via `$export_ok` variable in gitweb config file; see
|
||||
linkgit:gitweb.conf[5] manpage. If it evaluates to true, gitweb shows
|
||||
repositories only if this file named by `$export_ok` exists in its object
|
||||
database (if directory has the magic file named `$export_ok`).
|
||||
+
|
||||
For example linkgit:git-daemon[1] by default (unless `--export-all` option
|
||||
is used) allows pulling only for those repositories that have
|
||||
'git-daemon-export-ok' file. Adding
|
||||
+
|
||||
--------------------------------------------------------------------------
|
||||
our $export_ok = "git-daemon-export-ok";
|
||||
--------------------------------------------------------------------------
|
||||
+
|
||||
makes gitweb show and allow access only to those repositories that can be
|
||||
fetched from via `git://` protocol.
|
||||
|
||||
* Finally, it is possible to specify an arbitrary perl subroutine that will
|
||||
be called for each repository to determine if it can be exported. The
|
||||
subroutine receives an absolute path to the project (repository) as its only
|
||||
parameter (i.e. "$projectroot/$project").
|
||||
+
|
||||
For example, if you use mod_perl to run the script, and have dumb
|
||||
HTTP protocol authentication configured for your repositories, you
|
||||
can use the following hook to allow access only if the user is
|
||||
authorized to read the files:
|
||||
+
|
||||
--------------------------------------------------------------------------
|
||||
$export_auth_hook = sub {
|
||||
use Apache2::SubRequest ();
|
||||
use Apache2::Const -compile => qw(HTTP_OK);
|
||||
my $path = "$_[0]/HEAD";
|
||||
my $r = Apache2::RequestUtil->request;
|
||||
my $sub = $r->lookup_file($path);
|
||||
return $sub->filename eq $path
|
||||
&& $sub->status == Apache2::Const::HTTP_OK;
|
||||
};
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
|
||||
Per-repository gitweb configuration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
You can configure individual repositories shown in gitweb by creating file
|
||||
in the 'GIT_DIR' of git repository, or by setting some repo configuration
|
||||
variable (in 'GIT_DIR/config', see linkgit:git-config[1]).
|
||||
|
||||
You can use the following files in repository:
|
||||
|
||||
README.html::
|
||||
A html file (HTML fragment) which is included on the gitweb project
|
||||
"summary" page inside `<div>` block element. You can use it for longer
|
||||
description of a project, to provide links (for example to project's
|
||||
homepage), etc. This is recognized only if XSS prevention is off
|
||||
(`$prevent_xss` is false, see linkgit:gitweb.conf[5]); a way to include
|
||||
a README safely when XSS prevention is on may be worked out in the
|
||||
future.
|
||||
|
||||
description (or `gitweb.description`)::
|
||||
Short (shortened to `$projects_list_description_width` in the projects
|
||||
list page, which is 25 characters by default; see
|
||||
linkgit:gitweb.conf[5]) single line description of a project (of a
|
||||
repository). Plain text file; HTML will be escaped. By default set to
|
||||
+
|
||||
-------------------------------------------------------------------------------
|
||||
Unnamed repository; edit this file to name it for gitweb.
|
||||
-------------------------------------------------------------------------------
|
||||
+
|
||||
from the template during repository creation, usually installed in
|
||||
'/usr/share/git-core/templates/'. You can use the `gitweb.description` repo
|
||||
configuration variable, but the file takes precedence.
|
||||
|
||||
category (or `gitweb.category`)::
|
||||
Singe line category of a project, used to group projects if
|
||||
`$projects_list_group_categories` is enabled. By default (file and
|
||||
configuration variable absent), uncategorized projects are put in the
|
||||
`$project_list_default_category` category. You can use the
|
||||
`gitweb.category` repo configuration variable, but the file takes
|
||||
precedence.
|
||||
+
|
||||
The configuration variables `$projects_list_group_categories` and
|
||||
`$project_list_default_category` are described in linkgit:gitweb.conf[5]
|
||||
|
||||
cloneurl (or multiple-valued `gitweb.url`)::
|
||||
File with repository URL (used for clone and fetch), one per line.
|
||||
Displayed in the project summary page. You can use multiple-valued
|
||||
`gitweb.url` repository configuration variable for that, but the file
|
||||
takes precedence.
|
||||
+
|
||||
This is per-repository enhancement / version of global prefix-based
|
||||
`@git_base_url_list` gitweb configuration variable (see
|
||||
linkgit:gitweb.conf[5]).
|
||||
|
||||
gitweb.owner::
|
||||
You can use the `gitweb.owner` repository configuration variable to set
|
||||
repository's owner. It is displayed in the project list and summary
|
||||
page.
|
||||
+
|
||||
If it's not set, filesystem directory's owner is used (via GECOS field,
|
||||
i.e. real name field from *getpwuid*(3)) if `$projects_list` is unset
|
||||
(gitweb scans `$projectroot` for repositories); if `$projects_list`
|
||||
points to file with list of repositories, then project owner defaults to
|
||||
value from this file for given repository.
|
||||
|
||||
various `gitweb.*` config variables (in config)::
|
||||
Read description of `%feature` hash for detailed list, and descriptions.
|
||||
See also "Configuring gitweb features" section in linkgit:gitweb.conf[5]
|
||||
|
||||
|
||||
ACTIONS, AND URLS
|
||||
-----------------
|
||||
Gitweb can use path_info (component) based URLs, or it can pass all necessary
|
||||
information via query parameters. The typical gitweb URLs are broken down in to
|
||||
five components:
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
.../gitweb.cgi/<repo>/<action>/<revision>:/<path>?<arguments>
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
repo::
|
||||
The repository the action will be performed on.
|
||||
+
|
||||
All actions except for those that list all available projects,
|
||||
in whatever form, require this parameter.
|
||||
|
||||
action::
|
||||
The action that will be run. Defaults to 'projects_list' if repo
|
||||
is not set, and to 'summary' otherwise.
|
||||
|
||||
revision::
|
||||
Revision shown. Defaults to HEAD.
|
||||
|
||||
path::
|
||||
The path within the <repository> that the action is performed on,
|
||||
for those actions that require it.
|
||||
|
||||
arguments::
|
||||
Any arguments that control the behaviour of the action.
|
||||
|
||||
Some actions require or allow to specify two revisions, and sometimes even two
|
||||
pathnames. In most general form such path_info (component) based gitweb URL
|
||||
looks like this:
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
.../gitweb.cgi/<repo>/<action>/<revision_from>:/<path_from>..<revision_to>:/<path_to>?<arguments>
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
|
||||
Each action is implemented as a subroutine, and must be present in %actions
|
||||
hash. Some actions are disabled by default, and must be turned on via feature
|
||||
mechanism. For example to enable 'blame' view add the following to gitweb
|
||||
configuration file:
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
$feature{'blame'}{'default'} = [1];
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
|
||||
Actions:
|
||||
~~~~~~~~
|
||||
The standard actions are:
|
||||
|
||||
project_list::
|
||||
Lists the available Git repositories. This is the default command if no
|
||||
repository is specified in the URL.
|
||||
|
||||
summary::
|
||||
Displays summary about given repository. This is the default command if
|
||||
no action is specified in URL, and only repository is specified.
|
||||
|
||||
heads::
|
||||
remotes::
|
||||
Lists all local or all remote-tracking branches in given repository.
|
||||
+
|
||||
The latter is not available by default, unless configured.
|
||||
|
||||
tags::
|
||||
List all tags (lightweight and annotated) in given repository.
|
||||
|
||||
blob::
|
||||
tree::
|
||||
Shows the files and directories in a given repository path, at given
|
||||
revision. This is default command if no action is specified in the URL,
|
||||
and path is given.
|
||||
|
||||
blob_plain::
|
||||
Returns the raw data for the file in given repository, at given path and
|
||||
revision. Links to this action are marked 'raw'.
|
||||
|
||||
blobdiff::
|
||||
Shows the difference between two revisions of the same file.
|
||||
|
||||
blame::
|
||||
blame_incremental::
|
||||
Shows the blame (also called annotation) information for a file. On a
|
||||
per line basis it shows the revision in which that line was last changed
|
||||
and the user that committed the change. The incremental version (which
|
||||
if configured is used automatically when JavaScript is enabled) uses
|
||||
Ajax to incrementally add blame info to the contents of given file.
|
||||
+
|
||||
This action is disabled by default for performance reasons.
|
||||
|
||||
commit::
|
||||
commitdiff::
|
||||
Shows information about a specific commit in a repository. The 'commit'
|
||||
view shows information about commit in more detail, the 'commitdiff'
|
||||
action shows changeset for given commit.
|
||||
|
||||
patch::
|
||||
Returns the commit in plain text mail format, suitable for applying with
|
||||
linkgit:git-am[1].
|
||||
|
||||
tag::
|
||||
Display specific annotated tag (tag object).
|
||||
|
||||
log::
|
||||
shortlog::
|
||||
Shows log information (commit message or just commit subject) for a
|
||||
given branch (starting from given revision).
|
||||
+
|
||||
The 'shortlog' view is more compact; it shows one commit per line.
|
||||
|
||||
history::
|
||||
Shows history of the file or directory in a given repository path,
|
||||
starting from given revision (defaults to HEAD, i.e. default branch).
|
||||
+
|
||||
This view is similar to 'shortlog' view.
|
||||
|
||||
rss::
|
||||
atom::
|
||||
Generates an RSS (or Atom) feed of changes to repository.
|
||||
|
||||
|
||||
WEBSERVER CONFIGURATION
|
||||
-----------------------
|
||||
This section explains how to configure some common webservers to run gitweb. In
|
||||
all cases, `/path/to/gitweb` in the examples is the directory you ran installed
|
||||
gitweb in, and contains `gitweb_config.perl`.
|
||||
|
||||
If you've configured a web server that isn't listed here for gitweb, please send
|
||||
in the instructions so they can be included in a future release.
|
||||
|
||||
Apache as CGI
|
||||
~~~~~~~~~~~~~
|
||||
Apache must be configured to support CGI scripts in the directory in
|
||||
which gitweb is installed. Let's assume that it is '/var/www/cgi-bin'
|
||||
directory.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
|
||||
|
||||
<Directory "/var/www/cgi-bin">
|
||||
Options Indexes FollowSymlinks ExecCGI
|
||||
AllowOverride None
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
</Directory>
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
With that configuration the full path to browse repositories would be:
|
||||
|
||||
http://server/cgi-bin/gitweb.cgi
|
||||
|
||||
Apache with mod_perl, via ModPerl::Registry
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
You can use mod_perl with gitweb. You must install Apache::Registry
|
||||
(for mod_perl 1.x) or ModPerl::Registry (for mod_perl 2.x) to enable
|
||||
this support.
|
||||
|
||||
Assuming that gitweb is installed to '/var/www/perl', the following
|
||||
Apache configuration (for mod_perl 2.x) is suitable.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
Alias /perl "/var/www/perl"
|
||||
|
||||
<Directory "/var/www/perl">
|
||||
SetHandler perl-script
|
||||
PerlResponseHandler ModPerl::Registry
|
||||
PerlOptions +ParseHeaders
|
||||
Options Indexes FollowSymlinks +ExecCGI
|
||||
AllowOverride None
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
</Directory>
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
With that configuration the full path to browse repositories would be:
|
||||
|
||||
http://server/perl/gitweb.cgi
|
||||
|
||||
Apache with FastCGI
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
Gitweb works with Apache and FastCGI. First you need to rename, copy
|
||||
or symlink gitweb.cgi to gitweb.fcgi. Let's assume that gitweb is
|
||||
installed in '/usr/share/gitweb' directory. The following Apache
|
||||
configuration is suitable (UNTESTED!)
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
FastCgiServer /usr/share/gitweb/gitweb.cgi
|
||||
ScriptAlias /gitweb /usr/share/gitweb/gitweb.cgi
|
||||
|
||||
Alias /gitweb/static /usr/share/gitweb/static
|
||||
<Directory /usr/share/gitweb/static>
|
||||
SetHandler default-handler
|
||||
</Directory>
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
With that configuration the full path to browse repositories would be:
|
||||
|
||||
http://server/gitweb
|
||||
|
||||
|
||||
ADVANCED WEB SERVER SETUP
|
||||
-------------------------
|
||||
All of those examples use request rewriting, and need `mod_rewrite`
|
||||
(or equivalent; examples below are written for Apache).
|
||||
|
||||
Single URL for gitweb and for fetching
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
If you want to have one URL for both gitweb and your `http://`
|
||||
repositories, you can configure Apache like this:
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
<VirtualHost *:80>
|
||||
ServerName git.example.org
|
||||
DocumentRoot /pub/git
|
||||
SetEnv GITWEB_CONFIG /etc/gitweb.conf
|
||||
|
||||
# turning on mod rewrite
|
||||
RewriteEngine on
|
||||
|
||||
# make the front page an internal rewrite to the gitweb script
|
||||
RewriteRule ^/$ /cgi-bin/gitweb.cgi
|
||||
|
||||
# make access for "dumb clients" work
|
||||
RewriteRule ^/(.*\.git/(?!/?(HEAD|info|objects|refs)).*)?$ \
|
||||
/cgi-bin/gitweb.cgi%{REQUEST_URI} [L,PT]
|
||||
</VirtualHost>
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
The above configuration expects your public repositories to live under
|
||||
'/pub/git' and will serve them as `http://git.domain.org/dir-under-pub-git`,
|
||||
both as cloneable GIT URL and as browseable gitweb interface. If you then
|
||||
start your linkgit:git-daemon[1] with `--base-path=/pub/git --export-all`
|
||||
then you can even use the `git://` URL with exactly the same path.
|
||||
|
||||
Setting the environment variable `GITWEB_CONFIG` will tell gitweb to use the
|
||||
named file (i.e. in this example '/etc/gitweb.conf') as a configuration for
|
||||
gitweb. You don't really need it in above example; it is required only if
|
||||
your configuration file is in different place than built-in (during
|
||||
compiling gitweb) 'gitweb_config.perl' or '/etc/gitweb.conf'. See
|
||||
linkgit:gitweb.conf[5] for details, especially information about precedence
|
||||
rules.
|
||||
|
||||
If you use the rewrite rules from the example you *might* also need
|
||||
something like the following in your gitweb configuration file
|
||||
('/etc/gitweb.conf' following example):
|
||||
----------------------------------------------------------------------------
|
||||
@stylesheets = ("/some/absolute/path/gitweb.css");
|
||||
$my_uri = "/";
|
||||
$home_link = "/";
|
||||
$per_request_config = 1;
|
||||
----------------------------------------------------------------------------
|
||||
Nowadays though gitweb should create HTML base tag when needed (to set base
|
||||
URI for relative links), so it should work automatically.
|
||||
|
||||
|
||||
Webserver configuration with multiple projects' root
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
If you want to use gitweb with several project roots you can edit your
|
||||
Apache virtual host and gitweb configuration files in the following way.
|
||||
|
||||
The virtual host configuration (in Apache configuration file) should look
|
||||
like this:
|
||||
--------------------------------------------------------------------------
|
||||
<VirtualHost *:80>
|
||||
ServerName git.example.org
|
||||
DocumentRoot /pub/git
|
||||
SetEnv GITWEB_CONFIG /etc/gitweb.conf
|
||||
|
||||
# turning on mod rewrite
|
||||
RewriteEngine on
|
||||
|
||||
# make the front page an internal rewrite to the gitweb script
|
||||
RewriteRule ^/$ /cgi-bin/gitweb.cgi [QSA,L,PT]
|
||||
|
||||
# look for a public_git folder in unix users' home
|
||||
# http://git.example.org/~<user>/
|
||||
RewriteRule ^/\~([^\/]+)(/|/gitweb.cgi)?$ /cgi-bin/gitweb.cgi \
|
||||
[QSA,E=GITWEB_PROJECTROOT:/home/$1/public_git/,L,PT]
|
||||
|
||||
# http://git.example.org/+<user>/
|
||||
#RewriteRule ^/\+([^\/]+)(/|/gitweb.cgi)?$ /cgi-bin/gitweb.cgi \
|
||||
[QSA,E=GITWEB_PROJECTROOT:/home/$1/public_git/,L,PT]
|
||||
|
||||
# http://git.example.org/user/<user>/
|
||||
#RewriteRule ^/user/([^\/]+)/(gitweb.cgi)?$ /cgi-bin/gitweb.cgi \
|
||||
[QSA,E=GITWEB_PROJECTROOT:/home/$1/public_git/,L,PT]
|
||||
|
||||
# defined list of project roots
|
||||
RewriteRule ^/scm(/|/gitweb.cgi)?$ /cgi-bin/gitweb.cgi \
|
||||
[QSA,E=GITWEB_PROJECTROOT:/pub/scm/,L,PT]
|
||||
RewriteRule ^/var(/|/gitweb.cgi)?$ /cgi-bin/gitweb.cgi \
|
||||
[QSA,E=GITWEB_PROJECTROOT:/var/git/,L,PT]
|
||||
|
||||
# make access for "dumb clients" work
|
||||
RewriteRule ^/(.*\.git/(?!/?(HEAD|info|objects|refs)).*)?$ \
|
||||
/cgi-bin/gitweb.cgi%{REQUEST_URI} [L,PT]
|
||||
</VirtualHost>
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
Here actual project root is passed to gitweb via `GITWEB_PROJECT_ROOT`
|
||||
environment variable from a web server, so you need to put the following
|
||||
line in gitweb configuration file ('/etc/gitweb.conf' in above example):
|
||||
--------------------------------------------------------------------------
|
||||
$projectroot = $ENV{'GITWEB_PROJECTROOT'} || "/pub/git";
|
||||
--------------------------------------------------------------------------
|
||||
*Note* that this requires to be set for each request, so either
|
||||
`$per_request_config` must be false, or the above must be put in code
|
||||
referenced by `$per_request_config`;
|
||||
|
||||
These configurations enable two things. First, each unix user (`<user>`) of
|
||||
the server will be able to browse through gitweb git repositories found in
|
||||
'~/public_git/' with the following url:
|
||||
|
||||
http://git.example.org/~<user>/
|
||||
|
||||
If you do not want this feature on your server just remove the second
|
||||
rewrite rule.
|
||||
|
||||
If you already use `mod_userdir` in your virtual host or you don't want to
|
||||
use the \'~' as first character, just comment or remove the second rewrite
|
||||
rule, and uncomment one of the following according to what you want.
|
||||
|
||||
Second, repositories found in '/pub/scm/' and '/var/git/' will be accessible
|
||||
through `http://git.example.org/scm/` and `http://git.example.org/var/`.
|
||||
You can add as many project roots as you want by adding rewrite rules like
|
||||
the third and the fourth.
|
||||
|
||||
|
||||
PATH_INFO usage
|
||||
~~~~~~~~~~~~~~~
|
||||
If you enable PATH_INFO usage in gitweb by putting
|
||||
----------------------------------------------------------------------------
|
||||
$feature{'pathinfo'}{'default'} = [1];
|
||||
----------------------------------------------------------------------------
|
||||
in your gitweb configuration file, it is possible to set up your server so
|
||||
that it consumes and produces URLs in the form
|
||||
|
||||
http://git.example.com/project.git/shortlog/sometag
|
||||
|
||||
i.e. without 'gitweb.cgi' part, by using a configuration such as the
|
||||
following. This configuration assumes that '/var/www/gitweb' is the
|
||||
DocumentRoot of your webserver, contains the gitweb.cgi script and
|
||||
complementary static files (stylesheet, favicon, JavaScript):
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
<VirtualHost *:80>
|
||||
ServerAlias git.example.com
|
||||
|
||||
DocumentRoot /var/www/gitweb
|
||||
|
||||
<Directory /var/www/gitweb>
|
||||
Options ExecCGI
|
||||
AddHandler cgi-script cgi
|
||||
|
||||
DirectoryIndex gitweb.cgi
|
||||
|
||||
RewriteEngine On
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule ^.* /gitweb.cgi/$0 [L,PT]
|
||||
</Directory>
|
||||
</VirtualHost>
|
||||
----------------------------------------------------------------------------
|
||||
The rewrite rule guarantees that existing static files will be properly
|
||||
served, whereas any other URL will be passed to gitweb as PATH_INFO
|
||||
parameter.
|
||||
|
||||
*Notice* that in this case you don't need special settings for
|
||||
`@stylesheets`, `$my_uri` and `$home_link`, but you lose "dumb client"
|
||||
access to your project .git dirs (described in "Single URL for gitweb and
|
||||
for fetching" section). A possible workaround for the latter is the
|
||||
following: in your project root dir (e.g. '/pub/git') have the projects
|
||||
named *without* a .git extension (e.g. '/pub/git/project' instead of
|
||||
'/pub/git/project.git') and configure Apache as follows:
|
||||
----------------------------------------------------------------------------
|
||||
<VirtualHost *:80>
|
||||
ServerAlias git.example.com
|
||||
|
||||
DocumentRoot /var/www/gitweb
|
||||
|
||||
AliasMatch ^(/.*?)(\.git)(/.*)?$ /pub/git$1$3
|
||||
<Directory /var/www/gitweb>
|
||||
Options ExecCGI
|
||||
AddHandler cgi-script cgi
|
||||
|
||||
DirectoryIndex gitweb.cgi
|
||||
|
||||
RewriteEngine On
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule ^.* /gitweb.cgi/$0 [L,PT]
|
||||
</Directory>
|
||||
</VirtualHost>
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
The additional AliasMatch makes it so that
|
||||
|
||||
http://git.example.com/project.git
|
||||
|
||||
will give raw access to the project's git dir (so that the project can be
|
||||
cloned), while
|
||||
|
||||
http://git.example.com/project
|
||||
|
||||
will provide human-friendly gitweb access.
|
||||
|
||||
This solution is not 100% bulletproof, in the sense that if some project has
|
||||
a named ref (branch, tag) starting with 'git/', then paths such as
|
||||
|
||||
http://git.example.com/project/command/abranch..git/abranch
|
||||
|
||||
will fail with a 404 error.
|
||||
|
||||
|
||||
BUGS
|
||||
----
|
||||
Please report any bugs or feature requests to git@vger.kernel.org,
|
||||
putting "gitweb" in the subject of email.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
linkgit:gitweb.conf[5], linkgit:git-instaweb[1]
|
||||
|
||||
'gitweb/README', 'gitweb/INSTALL'
|
||||
|
||||
GIT
|
||||
---
|
||||
Part of the linkgit:git[1] suite
|
@ -176,7 +176,7 @@ by doing the following:
|
||||
- Update "What's cooking" message to review the updates to
|
||||
existing topics, newly added topics and graduated topics.
|
||||
|
||||
This step is helped with Meta/cook script (where Meta/ contains
|
||||
This step is helped with Meta/UWC script (where Meta/ contains
|
||||
a checkout of the 'todo' branch).
|
||||
|
||||
- Merge topics to 'next'. For each branch whose tip is not
|
||||
@ -197,9 +197,10 @@ by doing the following:
|
||||
|
||||
- Nothing is next-worthy; do not do anything.
|
||||
|
||||
- [** OBSOLETE **] Optionally rebase topics that do not have any commit
|
||||
in next yet, when they can take advantage of low-level framework
|
||||
change that is merged to 'master' already.
|
||||
- Rebase topics that do not have any commit in next yet. This
|
||||
step is optional but sometimes is worth doing when an old
|
||||
series that is not in next can take advantage of low-level
|
||||
framework change that is merged to 'master' already.
|
||||
|
||||
$ git rebase master ai/topic
|
||||
|
||||
@ -208,7 +209,7 @@ by doing the following:
|
||||
pre-rebase hook to make sure that topics that are already in
|
||||
'next' are not rebased beyond the merged commit.
|
||||
|
||||
- [** OBSOLETE **] Rebuild "pu" to merge the tips of topics not in 'next'.
|
||||
- Rebuild "pu" to merge the tips of topics not in 'next'.
|
||||
|
||||
$ git checkout pu
|
||||
$ git reset --hard next
|
||||
@ -240,7 +241,7 @@ by doing the following:
|
||||
|
||||
- Fetch html and man branches back from k.org, and push four
|
||||
integration branches and the two documentation branches to
|
||||
repo.or.cz and other mirrors.
|
||||
repo.or.cz
|
||||
|
||||
|
||||
Some observations to be made.
|
||||
|
@ -7,12 +7,6 @@ With --no-commit perform the merge but pretend the merge
|
||||
failed and do not autocommit, to give the user a chance to
|
||||
inspect and further tweak the merge result before committing.
|
||||
|
||||
--edit::
|
||||
-e::
|
||||
+
|
||||
Invoke editor before committing successful merge to further
|
||||
edit the default merge message.
|
||||
|
||||
--ff::
|
||||
--no-ff::
|
||||
Do not generate a merge commit if the merge resolved as
|
||||
|
@ -1,9 +0,0 @@
|
||||
--reset::
|
||||
Forget about the current operation in progress. Can be used
|
||||
to clear the sequencer state after a failed cherry-pick or
|
||||
revert.
|
||||
|
||||
--continue::
|
||||
Continue the operation in progress using the information in
|
||||
'.git/sequencer'. Can be used to continue after resolving
|
||||
conflicts in a failed cherry-pick or revert.
|
@ -1,46 +0,0 @@
|
||||
argv-array API
|
||||
==============
|
||||
|
||||
The argv-array API allows one to dynamically build and store
|
||||
NULL-terminated lists. An argv-array maintains the invariant that the
|
||||
`argv` member always points to a non-NULL array, and that the array is
|
||||
always NULL-terminated at the element pointed to by `argv[argc]`. This
|
||||
makes the result suitable for passing to functions expecting to receive
|
||||
argv from main(), or the link:api-run-command.html[run-command API].
|
||||
|
||||
The link:api-string-list.html[string-list API] is similar, but cannot be
|
||||
used for these purposes; instead of storing a straight string pointer,
|
||||
it contains an item structure with a `util` field that is not compatible
|
||||
with the traditional argv interface.
|
||||
|
||||
Each `argv_array` manages its own memory. Any strings pushed into the
|
||||
array are duplicated, and all memory is freed by argv_array_clear().
|
||||
|
||||
Data Structures
|
||||
---------------
|
||||
|
||||
`struct argv_array`::
|
||||
|
||||
A single array. This should be initialized by assignment from
|
||||
`ARGV_ARRAY_INIT`, or by calling `argv_array_init`. The `argv`
|
||||
member contains the actual array; the `argc` member contains the
|
||||
number of elements in the array, not including the terminating
|
||||
NULL.
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
`argv_array_init`::
|
||||
Initialize an array. This is no different than assigning from
|
||||
`ARGV_ARRAY_INIT`.
|
||||
|
||||
`argv_array_push`::
|
||||
Push a copy of a string onto the end of the array.
|
||||
|
||||
`argv_array_pushf`::
|
||||
Format a string and push it onto the end of the array. This is a
|
||||
convenience wrapper combining `strbuf_addf` and `argv_array_push`.
|
||||
|
||||
`argv_array_clear`::
|
||||
Free all memory associated with the array and return it to the
|
||||
initial, empty state.
|
@ -11,15 +11,27 @@ Data Structure
|
||||
`struct git_attr`::
|
||||
|
||||
An attribute is an opaque object that is identified by its name.
|
||||
Pass the name to `git_attr()` function to obtain the object of
|
||||
this type. The internal representation of this structure is
|
||||
of no interest to the calling programs. The name of the
|
||||
attribute can be retrieved by calling `git_attr_name()`.
|
||||
Pass the name and its length to `git_attr()` function to obtain
|
||||
the object of this type. The internal representation of this
|
||||
structure is of no interest to the calling programs.
|
||||
|
||||
`struct git_attr_check`::
|
||||
|
||||
This structure represents a set of attributes to check in a call
|
||||
to `git_check_attr()` function, and receives the results.
|
||||
to `git_checkattr()` function, and receives the results.
|
||||
|
||||
|
||||
Calling Sequence
|
||||
----------------
|
||||
|
||||
* Prepare an array of `struct git_attr_check` to define the list of
|
||||
attributes you would want to check. To populate this array, you would
|
||||
need to define necessary attributes by calling `git_attr()` function.
|
||||
|
||||
* Call git_checkattr() to check the attributes for the path.
|
||||
|
||||
* Inspect `git_attr_check` structure to see how each of the attribute in
|
||||
the array is defined for the path.
|
||||
|
||||
|
||||
Attribute Values
|
||||
@ -45,19 +57,6 @@ If none of the above returns true, `.value` member points at a string
|
||||
value of the attribute for the path.
|
||||
|
||||
|
||||
Querying Specific Attributes
|
||||
----------------------------
|
||||
|
||||
* Prepare an array of `struct git_attr_check` to define the list of
|
||||
attributes you would want to check. To populate this array, you would
|
||||
need to define necessary attributes by calling `git_attr()` function.
|
||||
|
||||
* Call `git_check_attr()` to check the attributes for the path.
|
||||
|
||||
* Inspect `git_attr_check` structure to see how each of the attribute in
|
||||
the array is defined for the path.
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
@ -73,18 +72,18 @@ static void setup_check(void)
|
||||
{
|
||||
if (check[0].attr)
|
||||
return; /* already done */
|
||||
check[0].attr = git_attr("crlf");
|
||||
check[1].attr = git_attr("ident");
|
||||
check[0].attr = git_attr("crlf", 4);
|
||||
check[1].attr = git_attr("ident", 5);
|
||||
}
|
||||
------------
|
||||
|
||||
. Call `git_check_attr()` with the prepared array of `struct git_attr_check`:
|
||||
. Call `git_checkattr()` with the prepared array of `struct git_attr_check`:
|
||||
|
||||
------------
|
||||
const char *path;
|
||||
|
||||
setup_check();
|
||||
git_check_attr(path, ARRAY_SIZE(check), check);
|
||||
git_checkattr(path, ARRAY_SIZE(check), check);
|
||||
------------
|
||||
|
||||
. Act on `.value` member of the result, left in `check[]`:
|
||||
@ -109,20 +108,4 @@ static void setup_check(void)
|
||||
}
|
||||
------------
|
||||
|
||||
|
||||
Querying All Attributes
|
||||
-----------------------
|
||||
|
||||
To get the values of all attributes associated with a file:
|
||||
|
||||
* Call `git_all_attrs()`, which returns an array of `git_attr_check`
|
||||
structures.
|
||||
|
||||
* Iterate over the `git_attr_check` array to examine the attribute
|
||||
names and values. The name of the attribute described by a
|
||||
`git_attr_check` object can be retrieved via
|
||||
`git_attr_name(check[i].attr)`. (Please note that no items will be
|
||||
returned for unset attributes, so `ATTR_UNSET()` will return false
|
||||
for all returned `git_array_check` objects.)
|
||||
|
||||
* Free the `git_array_check` array.
|
||||
(JC)
|
||||
|
@ -135,14 +135,9 @@ There are some macros to easily define options:
|
||||
describes the group or an empty string.
|
||||
Start the description with an upper-case letter.
|
||||
|
||||
`OPT_BOOL(short, long, &int_var, description)`::
|
||||
Introduce a boolean option. `int_var` is set to one with
|
||||
`--option` and set to zero with `--no-option`.
|
||||
|
||||
`OPT_COUNTUP(short, long, &int_var, description)`::
|
||||
Introduce a count-up option.
|
||||
`int_var` is incremented on each use of `--option`, and
|
||||
reset to zero with `--no-option`.
|
||||
`OPT_BOOLEAN(short, long, &int_var, description)`::
|
||||
Introduce a boolean option.
|
||||
`int_var` is incremented on each use.
|
||||
|
||||
`OPT_BIT(short, long, &int_var, description, mask)`::
|
||||
Introduce a boolean option.
|
||||
@ -153,9 +148,8 @@ There are some macros to easily define options:
|
||||
If used, `int_var` is bitwise-anded with the inverted `mask`.
|
||||
|
||||
`OPT_SET_INT(short, long, &int_var, description, integer)`::
|
||||
Introduce an integer option.
|
||||
`int_var` is set to `integer` with `--option`, and
|
||||
reset to zero with `--no-option`.
|
||||
Introduce a boolean option.
|
||||
If used, set `int_var` to `integer`.
|
||||
|
||||
`OPT_SET_PTR(short, long, &ptr_var, description, ptr)`::
|
||||
Introduce a boolean option.
|
||||
@ -204,11 +198,6 @@ There are some macros to easily define options:
|
||||
"auto", set `int_var` to 1 if stdout is a tty or a pager,
|
||||
0 otherwise.
|
||||
|
||||
`OPT_NOOP_NOARG(short, long)`::
|
||||
Introduce an option that has no effect and takes no arguments.
|
||||
Use it to hide deprecated options that are still to be recognized
|
||||
and ignored silently.
|
||||
|
||||
|
||||
The last element of the array must be `OPT_END()`.
|
||||
|
||||
|
@ -1,79 +0,0 @@
|
||||
sha1-array API
|
||||
==============
|
||||
|
||||
The sha1-array API provides storage and manipulation of sets of SHA1
|
||||
identifiers. The emphasis is on storage and processing efficiency,
|
||||
making them suitable for large lists. Note that the ordering of items is
|
||||
not preserved over some operations.
|
||||
|
||||
Data Structures
|
||||
---------------
|
||||
|
||||
`struct sha1_array`::
|
||||
|
||||
A single array of SHA1 hashes. This should be initialized by
|
||||
assignment from `SHA1_ARRAY_INIT`. The `sha1` member contains
|
||||
the actual data. The `nr` member contains the number of items in
|
||||
the set. The `alloc` and `sorted` members are used internally,
|
||||
and should not be needed by API callers.
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
`sha1_array_append`::
|
||||
Add an item to the set. The sha1 will be placed at the end of
|
||||
the array (but note that some operations below may lose this
|
||||
ordering).
|
||||
|
||||
`sha1_array_sort`::
|
||||
Sort the elements in the array.
|
||||
|
||||
`sha1_array_lookup`::
|
||||
Perform a binary search of the array for a specific sha1.
|
||||
If found, returns the offset (in number of elements) of the
|
||||
sha1. If not found, returns a negative integer. If the array is
|
||||
not sorted, this function has the side effect of sorting it.
|
||||
|
||||
`sha1_array_clear`::
|
||||
Free all memory associated with the array and return it to the
|
||||
initial, empty state.
|
||||
|
||||
`sha1_array_for_each_unique`::
|
||||
Efficiently iterate over each unique element of the list,
|
||||
executing the callback function for each one. If the array is
|
||||
not sorted, this function has the side effect of sorting it.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
-----------------------------------------
|
||||
void print_callback(const unsigned char sha1[20],
|
||||
void *data)
|
||||
{
|
||||
printf("%s\n", sha1_to_hex(sha1));
|
||||
}
|
||||
|
||||
void some_func(void)
|
||||
{
|
||||
struct sha1_array hashes = SHA1_ARRAY_INIT;
|
||||
unsigned char sha1[20];
|
||||
|
||||
/* Read objects into our set */
|
||||
while (read_object_from_stdin(sha1))
|
||||
sha1_array_append(&hashes, sha1);
|
||||
|
||||
/* Check if some objects are in our set */
|
||||
while (read_object_from_stdin(sha1)) {
|
||||
if (sha1_array_lookup(&hashes, sha1) >= 0)
|
||||
printf("it's in there!\n");
|
||||
|
||||
/*
|
||||
* Print the unique set of objects. We could also have
|
||||
* avoided adding duplicate objects in the first place,
|
||||
* but we would end up re-sorting the array repeatedly.
|
||||
* Instead, this will sort once and then skip duplicates
|
||||
* in linear time.
|
||||
*/
|
||||
sha1_array_for_each_unique(&hashes, print_callback, NULL);
|
||||
}
|
||||
-----------------------------------------
|
@ -29,9 +29,6 @@ member (you need this if you add things later) and you should set the
|
||||
|
||||
. Can sort an unsorted list using `sort_string_list`.
|
||||
|
||||
. Can remove individual items of an unsorted list using
|
||||
`unsorted_string_list_delete_item`.
|
||||
|
||||
. Finally it should free the list using `string_list_clear`.
|
||||
|
||||
Example:
|
||||
@ -115,13 +112,6 @@ write `string_list_insert(...)->util = ...;`.
|
||||
The above two functions need to look through all items, as opposed to their
|
||||
counterpart for sorted lists, which performs a binary search.
|
||||
|
||||
`unsorted_string_list_delete_item`::
|
||||
|
||||
Remove an item from a string_list. The `string` pointer of the items
|
||||
will be freed in case the `strdup_strings` member of the string_list
|
||||
is set. The third parameter controls if the `util` pointer of the
|
||||
items should be freed or not.
|
||||
|
||||
Data structures
|
||||
---------------
|
||||
|
||||
|
@ -60,13 +60,6 @@ process on the server side over the Git protocol is this:
|
||||
"0039git-upload-pack /schacon/gitbook.git\0host=example.com\0" |
|
||||
nc -v example.com 9418
|
||||
|
||||
If the server refuses the request for some reasons, it could abort
|
||||
gracefully with an error message.
|
||||
|
||||
----
|
||||
error-line = PKT-LINE("ERR" SP explanation-text)
|
||||
----
|
||||
|
||||
|
||||
SSH Transport
|
||||
-------------
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
GVF=GIT-VERSION-FILE
|
||||
DEF_VER=v1.7.8-rc0
|
||||
DEF_VER=v1.7.6.6
|
||||
|
||||
LF='
|
||||
'
|
||||
|
13
INSTALL
13
INSTALL
@ -25,19 +25,6 @@ set up install paths (via config.mak.autogen), so you can write instead
|
||||
$ make all doc ;# as yourself
|
||||
# make install install-doc install-html;# as root
|
||||
|
||||
If you're willing to trade off (much) longer build time for a later
|
||||
faster git you can also do a profile feedback build with
|
||||
|
||||
$ make profile-all
|
||||
# make prefix=... install
|
||||
|
||||
This will run the complete test suite as training workload and then
|
||||
rebuild git with the generated profile feedback. This results in a git
|
||||
which is a few percent faster on CPU intensive workloads. This
|
||||
may be a good tradeoff for distribution packagers.
|
||||
|
||||
Note that the profile feedback build stage currently generates
|
||||
a lot of additional compiler warnings.
|
||||
|
||||
Issues of note:
|
||||
|
||||
|
117
Makefile
117
Makefile
@ -30,15 +30,15 @@ all::
|
||||
# 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-fetch and
|
||||
# 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 (neither smart nor dumb).
|
||||
# transports.
|
||||
#
|
||||
# Define CURLDIR=/foo/bar if your curl header and library files are in
|
||||
# /foo/bar/include and /foo/bar/lib directories.
|
||||
#
|
||||
# Define NO_EXPAT if you do not have expat installed. git-http-push is
|
||||
# not built, and you cannot push using http:// and https:// transports (dumb).
|
||||
# not built, and you cannot push using http:// and https:// transports.
|
||||
#
|
||||
# Define EXPATDIR=/foo/bar if your expat header and library files are in
|
||||
# /foo/bar/include and /foo/bar/lib directories.
|
||||
@ -115,10 +115,6 @@ all::
|
||||
#
|
||||
# Define NEEDS_SSL_WITH_CRYPTO if you need -lssl when using -lcrypto (Darwin).
|
||||
#
|
||||
# Define NEEDS_SSL_WITH_CURL if you need -lssl with -lcurl (Minix).
|
||||
#
|
||||
# Define NEEDS_IDN_WITH_CURL if you need -lidn when using -lcurl (Minix).
|
||||
#
|
||||
# Define NEEDS_LIBICONV if linking with libc is not enough (Darwin).
|
||||
#
|
||||
# Define NEEDS_SOCKET if linking with libc is not enough (SunOS,
|
||||
@ -157,9 +153,6 @@ all::
|
||||
# that tells runtime paths to dynamic libraries;
|
||||
# "-Wl,-rpath=/path/lib" is used instead.
|
||||
#
|
||||
# Define NO_NORETURN if using buggy versions of gcc 4.6+ and profile feedback,
|
||||
# as the compiler can crash (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49299)
|
||||
#
|
||||
# Define USE_NSEC below if you want git to care about sub-second file mtimes
|
||||
# and ctimes. Note that you need recent glibc (at least 2.2.4) for this, and
|
||||
# it will BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely
|
||||
@ -250,6 +243,10 @@ all::
|
||||
# DEFAULT_EDITOR='$GIT_FALLBACK_EDITOR',
|
||||
# DEFAULT_EDITOR='"C:\Program Files\Vim\gvim.exe" --nofork'
|
||||
#
|
||||
# Define COMPUTE_HEADER_DEPENDENCIES if your compiler supports the -MMD option
|
||||
# and you want to avoid rebuilding objects when an unrelated header file
|
||||
# changes.
|
||||
#
|
||||
# Define CHECK_HEADER_DEPENDENCIES to check for problems in the hard-coded
|
||||
# dependency rules.
|
||||
#
|
||||
@ -298,7 +295,6 @@ bindir = $(prefix)/$(bindir_relative)
|
||||
mandir = share/man
|
||||
infodir = share/info
|
||||
gitexecdir = libexec/git-core
|
||||
mergetoolsdir = $(gitexecdir)/mergetools
|
||||
sharedir = $(prefix)/share
|
||||
gitwebdir = $(sharedir)/gitweb
|
||||
template_dir = share/git-core/templates
|
||||
@ -501,7 +497,6 @@ VCSSVN_LIB=vcs-svn/lib.a
|
||||
|
||||
LIB_H += advice.h
|
||||
LIB_H += archive.h
|
||||
LIB_H += argv-array.h
|
||||
LIB_H += attr.h
|
||||
LIB_H += blob.h
|
||||
LIB_H += builtin.h
|
||||
@ -512,12 +507,10 @@ LIB_H += commit.h
|
||||
LIB_H += compat/bswap.h
|
||||
LIB_H += compat/cygwin.h
|
||||
LIB_H += compat/mingw.h
|
||||
LIB_H += compat/obstack.h
|
||||
LIB_H += compat/win32/pthread.h
|
||||
LIB_H += compat/win32/syslog.h
|
||||
LIB_H += compat/win32/sys/poll.h
|
||||
LIB_H += compat/win32/dirent.h
|
||||
LIB_H += connected.h
|
||||
LIB_H += csum-file.h
|
||||
LIB_H += decorate.h
|
||||
LIB_H += delta.h
|
||||
@ -532,7 +525,6 @@ LIB_H += graph.h
|
||||
LIB_H += grep.h
|
||||
LIB_H += hash.h
|
||||
LIB_H += help.h
|
||||
LIB_H += kwset.h
|
||||
LIB_H += levenshtein.h
|
||||
LIB_H += list-objects.h
|
||||
LIB_H += ll-merge.h
|
||||
@ -559,13 +551,11 @@ LIB_H += rerere.h
|
||||
LIB_H += resolve-undo.h
|
||||
LIB_H += revision.h
|
||||
LIB_H += run-command.h
|
||||
LIB_H += sequencer.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
|
||||
@ -585,7 +575,6 @@ LIB_OBJS += alloc.o
|
||||
LIB_OBJS += archive.o
|
||||
LIB_OBJS += archive-tar.o
|
||||
LIB_OBJS += archive-zip.o
|
||||
LIB_OBJS += argv-array.o
|
||||
LIB_OBJS += attr.o
|
||||
LIB_OBJS += base85.o
|
||||
LIB_OBJS += bisect.o
|
||||
@ -596,10 +585,8 @@ LIB_OBJS += cache-tree.o
|
||||
LIB_OBJS += color.o
|
||||
LIB_OBJS += combine-diff.o
|
||||
LIB_OBJS += commit.o
|
||||
LIB_OBJS += compat/obstack.o
|
||||
LIB_OBJS += config.o
|
||||
LIB_OBJS += connect.o
|
||||
LIB_OBJS += connected.o
|
||||
LIB_OBJS += convert.o
|
||||
LIB_OBJS += copy.o
|
||||
LIB_OBJS += csum-file.o
|
||||
@ -627,7 +614,6 @@ LIB_OBJS += hash.o
|
||||
LIB_OBJS += help.o
|
||||
LIB_OBJS += hex.o
|
||||
LIB_OBJS += ident.o
|
||||
LIB_OBJS += kwset.o
|
||||
LIB_OBJS += levenshtein.o
|
||||
LIB_OBJS += list-objects.o
|
||||
LIB_OBJS += ll-merge.o
|
||||
@ -648,7 +634,6 @@ LIB_OBJS += pack-revindex.o
|
||||
LIB_OBJS += pack-write.o
|
||||
LIB_OBJS += pager.o
|
||||
LIB_OBJS += parse-options.o
|
||||
LIB_OBJS += parse-options-cb.o
|
||||
LIB_OBJS += patch-delta.o
|
||||
LIB_OBJS += patch-ids.o
|
||||
LIB_OBJS += path.o
|
||||
@ -669,7 +654,6 @@ LIB_OBJS += revision.o
|
||||
LIB_OBJS += run-command.o
|
||||
LIB_OBJS += server-info.o
|
||||
LIB_OBJS += setup.o
|
||||
LIB_OBJS += sequencer.o
|
||||
LIB_OBJS += sha1-array.o
|
||||
LIB_OBJS += sha1-lookup.o
|
||||
LIB_OBJS += sha1_file.o
|
||||
@ -678,7 +662,6 @@ 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
|
||||
@ -822,7 +805,6 @@ ifeq ($(uname_S),GNU/kFreeBSD)
|
||||
NO_STRLCPY = YesPlease
|
||||
NO_MKSTEMPS = YesPlease
|
||||
HAVE_PATHS_H = YesPlease
|
||||
DIR_HAS_BSD_GROUP_SEMANTICS = YesPlease
|
||||
endif
|
||||
ifeq ($(uname_S),UnixWare)
|
||||
CC = cc
|
||||
@ -1142,6 +1124,8 @@ endif
|
||||
X = .exe
|
||||
endif
|
||||
ifeq ($(uname_S),Interix)
|
||||
NO_SYS_POLL_H = YesPlease
|
||||
NO_INTTYPES_H = YesPlease
|
||||
NO_INITGROUPS = YesPlease
|
||||
NO_IPV6 = YesPlease
|
||||
NO_MEMMEM = YesPlease
|
||||
@ -1152,30 +1136,12 @@ ifeq ($(uname_S),Interix)
|
||||
ifeq ($(uname_R),3.5)
|
||||
NO_INET_NTOP = YesPlease
|
||||
NO_INET_PTON = YesPlease
|
||||
NO_SOCKADDR_STORAGE = YesPlease
|
||||
NO_FNMATCH_CASEFOLD = YesPlease
|
||||
endif
|
||||
ifeq ($(uname_R),5.2)
|
||||
NO_INET_NTOP = YesPlease
|
||||
NO_INET_PTON = YesPlease
|
||||
NO_SOCKADDR_STORAGE = YesPlease
|
||||
NO_FNMATCH_CASEFOLD = YesPlease
|
||||
endif
|
||||
endif
|
||||
ifeq ($(uname_S),Minix)
|
||||
NO_IPV6 = YesPlease
|
||||
NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
|
||||
NO_NSEC = YesPlease
|
||||
NEEDS_LIBGEN =
|
||||
NEEDS_CRYPTO_WITH_SSL = YesPlease
|
||||
NEEDS_IDN_WITH_CURL = YesPlease
|
||||
NEEDS_SSL_WITH_CURL = YesPlease
|
||||
NEEDS_RESOLV =
|
||||
NO_HSTRERROR = YesPlease
|
||||
NO_MMAP = YesPlease
|
||||
NO_CURL =
|
||||
NO_EXPAT =
|
||||
endif
|
||||
ifneq (,$(findstring MINGW,$(uname_S)))
|
||||
pathsep = ;
|
||||
NO_PREAD = YesPlease
|
||||
@ -1245,15 +1211,6 @@ endif
|
||||
ifdef CHECK_HEADER_DEPENDENCIES
|
||||
COMPUTE_HEADER_DEPENDENCIES =
|
||||
USE_COMPUTED_HEADER_DEPENDENCIES =
|
||||
else
|
||||
ifndef COMPUTE_HEADER_DEPENDENCIES
|
||||
dep_check = $(shell $(CC) $(ALL_CFLAGS) \
|
||||
-c -MF /dev/null -MMD -MP -x c /dev/null -o /dev/null 2>&1; \
|
||||
echo $$?)
|
||||
ifeq ($(dep_check),0)
|
||||
COMPUTE_HEADER_DEPENDENCIES=YesPlease
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef COMPUTE_HEADER_DEPENDENCIES
|
||||
@ -1329,16 +1286,6 @@ else
|
||||
else
|
||||
CURL_LIBCURL = -lcurl
|
||||
endif
|
||||
ifdef NEEDS_SSL_WITH_CURL
|
||||
CURL_LIBCURL += -lssl
|
||||
ifdef NEEDS_CRYPTO_WITH_SSL
|
||||
CURL_LIBCURL += -lcrypto
|
||||
endif
|
||||
endif
|
||||
ifdef NEEDS_IDN_WITH_CURL
|
||||
CURL_LIBCURL += -lidn
|
||||
endif
|
||||
|
||||
REMOTE_CURL_PRIMARY = git-remote-http$X
|
||||
REMOTE_CURL_ALIASES = git-remote-https$X git-remote-ftp$X git-remote-ftps$X
|
||||
REMOTE_CURL_NAMES = $(REMOTE_CURL_PRIMARY) $(REMOTE_CURL_ALIASES)
|
||||
@ -1375,7 +1322,7 @@ ifndef NO_OPENSSL
|
||||
OPENSSL_LINK =
|
||||
endif
|
||||
ifdef NEEDS_CRYPTO_WITH_SSL
|
||||
OPENSSL_LIBSSL += -lcrypto
|
||||
OPENSSL_LINK += -lcrypto
|
||||
endif
|
||||
else
|
||||
BASIC_CFLAGS += -DNO_OPENSSL
|
||||
@ -1427,9 +1374,6 @@ endif
|
||||
ifdef USE_ST_TIMESPEC
|
||||
BASIC_CFLAGS += -DUSE_ST_TIMESPEC
|
||||
endif
|
||||
ifdef NO_NORETURN
|
||||
BASIC_CFLAGS += -DNO_NORETURN
|
||||
endif
|
||||
ifdef NO_NSEC
|
||||
BASIC_CFLAGS += -DNO_NSEC
|
||||
endif
|
||||
@ -1894,7 +1838,7 @@ ifndef NO_CURL
|
||||
GIT_OBJS += http.o http-walker.o remote-curl.o
|
||||
endif
|
||||
XDIFF_OBJS = xdiff/xdiffi.o xdiff/xprepare.o xdiff/xutils.o xdiff/xemit.o \
|
||||
xdiff/xmerge.o xdiff/xpatience.o xdiff/xhistogram.o
|
||||
xdiff/xmerge.o xdiff/xpatience.o
|
||||
VCSSVN_OBJS = vcs-svn/string_pool.o vcs-svn/line_buffer.o \
|
||||
vcs-svn/repo_tree.o vcs-svn/fast_export.o vcs-svn/svndump.o
|
||||
VCSSVN_TEST_OBJS = test-obj-pool.o test-string-pool.o \
|
||||
@ -1906,7 +1850,7 @@ dep_dirs := $(addsuffix .depend,$(sort $(dir $(OBJECTS))))
|
||||
|
||||
ifdef COMPUTE_HEADER_DEPENDENCIES
|
||||
$(dep_dirs):
|
||||
@mkdir -p $@
|
||||
mkdir -p $@
|
||||
|
||||
missing_dep_dirs := $(filter-out $(wildcard $(dep_dirs)),$(dep_dirs))
|
||||
dep_file = $(dir $@).depend/$(notdir $@).d
|
||||
@ -2127,21 +2071,17 @@ po/git.pot: $(LOCALIZED_C)
|
||||
|
||||
pot: po/git.pot
|
||||
|
||||
FIND_SOURCE_FILES = ( git ls-files '*.[hcS]' 2>/dev/null || \
|
||||
$(FIND) . \( -name .git -type d -prune \) \
|
||||
-o \( -name '*.[hcS]' -type f -print \) )
|
||||
|
||||
$(ETAGS_TARGET): FORCE
|
||||
$(RM) $(ETAGS_TARGET)
|
||||
$(FIND_SOURCE_FILES) | xargs etags -a -o $(ETAGS_TARGET)
|
||||
$(FIND) . -name '*.[hcS]' -print | xargs etags -a -o $(ETAGS_TARGET)
|
||||
|
||||
tags: FORCE
|
||||
$(RM) tags
|
||||
$(FIND_SOURCE_FILES) | xargs ctags -a
|
||||
$(FIND) . -name '*.[hcS]' -print | xargs ctags -a
|
||||
|
||||
cscope:
|
||||
$(RM) cscope*
|
||||
$(FIND_SOURCE_FILES) | xargs cscope -b
|
||||
$(FIND) . -name '*.[hcS]' -print | xargs cscope -b
|
||||
|
||||
### Detect prefix changes
|
||||
TRACK_CFLAGS = $(CC):$(subst ','\'',$(ALL_CFLAGS)):\
|
||||
@ -2226,7 +2166,7 @@ test-delta$X: diff-delta.o patch-delta.o
|
||||
|
||||
test-line-buffer$X: vcs-svn/lib.a
|
||||
|
||||
test-parse-options$X: parse-options.o parse-options-cb.o
|
||||
test-parse-options$X: parse-options.o
|
||||
|
||||
test-string-pool$X: vcs-svn/lib.a
|
||||
|
||||
@ -2279,13 +2219,6 @@ endif
|
||||
gitexec_instdir_SQ = $(subst ','\'',$(gitexec_instdir))
|
||||
export gitexec_instdir
|
||||
|
||||
ifneq ($(filter /%,$(firstword $(mergetoolsdir))),)
|
||||
mergetools_instdir = $(mergetoolsdir)
|
||||
else
|
||||
mergetools_instdir = $(prefix)/$(mergetoolsdir)
|
||||
endif
|
||||
mergetools_instdir_SQ = $(subst ','\'',$(mergetools_instdir))
|
||||
|
||||
install_bindir_programs := $(patsubst %,%$X,$(BINDIR_PROGRAMS_NEED_X)) $(BINDIR_PROGRAMS_NO_X)
|
||||
|
||||
install: all
|
||||
@ -2295,8 +2228,6 @@ install: all
|
||||
$(INSTALL) -m 644 $(SCRIPT_LIB) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
|
||||
$(INSTALL) $(install_bindir_programs) '$(DESTDIR_SQ)$(bindir_SQ)'
|
||||
$(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'
|
||||
$(INSTALL) -m 644 mergetools/* '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'
|
||||
ifndef NO_PERL
|
||||
$(MAKE) -C perl prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' install
|
||||
$(MAKE) -C gitweb install
|
||||
@ -2564,19 +2495,3 @@ cover_db: coverage-report
|
||||
|
||||
cover_db_html: cover_db
|
||||
cover -report html -outputdir cover_db_html cover_db
|
||||
|
||||
### profile feedback build
|
||||
#
|
||||
.PHONY: profile-all profile-clean
|
||||
|
||||
PROFILE_GEN_CFLAGS := $(CFLAGS) -fprofile-generate -DNO_NORETURN=1
|
||||
PROFILE_USE_CFLAGS := $(CFLAGS) -fprofile-use -fprofile-correction -DNO_NORETURN=1
|
||||
|
||||
profile-clean:
|
||||
$(RM) $(addsuffix *.gcda,$(object_dirs))
|
||||
$(RM) $(addsuffix *.gcno,$(object_dirs))
|
||||
|
||||
profile-all: profile-clean
|
||||
$(MAKE) CFLAGS="$(PROFILE_GEN_CFLAGS)" all
|
||||
$(MAKE) CFLAGS="$(PROFILE_GEN_CFLAGS)" -j1 test
|
||||
$(MAKE) CFLAGS="$(PROFILE_USE_CFLAGS)" all
|
||||
|
32
abspath.c
32
abspath.c
@ -40,7 +40,7 @@ const char *real_path(const char *path)
|
||||
|
||||
while (depth--) {
|
||||
if (!is_directory(buf)) {
|
||||
char *last_slash = find_last_dir_sep(buf);
|
||||
char *last_slash = strrchr(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 && !is_dir_sep(buf[len-1]))
|
||||
if (len && buf[len-1] != '/')
|
||||
buf[len++] = '/';
|
||||
strcpy(buf + len, last_elem);
|
||||
free(last_elem);
|
||||
@ -139,31 +139,3 @@ const char *absolute_path(const char *path)
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unlike prefix_path, this should be used if the named file does
|
||||
* not have to interact with index entry; i.e. name of a random file
|
||||
* on the filesystem.
|
||||
*/
|
||||
const char *prefix_filename(const char *pfx, int pfx_len, const char *arg)
|
||||
{
|
||||
static char path[PATH_MAX];
|
||||
#ifndef WIN32
|
||||
if (!pfx_len || is_absolute_path(arg))
|
||||
return arg;
|
||||
memcpy(path, pfx, pfx_len);
|
||||
strcpy(path + pfx_len, arg);
|
||||
#else
|
||||
char *p;
|
||||
/* don't add prefix to absolute paths, but still replace '\' by '/' */
|
||||
if (is_absolute_path(arg))
|
||||
pfx_len = 0;
|
||||
else if (pfx_len)
|
||||
memcpy(path, pfx, pfx_len);
|
||||
strcpy(path + pfx_len, arg);
|
||||
for (p = path + pfx_len; *p; p++)
|
||||
if (*p == '\\')
|
||||
*p = '/';
|
||||
#endif
|
||||
return path;
|
||||
}
|
||||
|
31
advice.c
31
advice.c
@ -19,15 +19,6 @@ static struct {
|
||||
{ "detachedhead", &advice_detached_head },
|
||||
};
|
||||
|
||||
void advise(const char *advice, ...)
|
||||
{
|
||||
va_list params;
|
||||
|
||||
va_start(params, advice);
|
||||
vreportf("hint: ", advice, params);
|
||||
va_end(params);
|
||||
}
|
||||
|
||||
int git_default_advice_config(const char *var, const char *value)
|
||||
{
|
||||
const char *k = skip_prefix(var, "advice.");
|
||||
@ -43,24 +34,16 @@ int git_default_advice_config(const char *var, const char *value)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int error_resolve_conflict(const char *me)
|
||||
void NORETURN die_resolve_conflict(const char *me)
|
||||
{
|
||||
error("'%s' is not possible because you have unmerged files.", me);
|
||||
if (advice_resolve_conflict) {
|
||||
if (advice_resolve_conflict)
|
||||
/*
|
||||
* Message used both when 'git commit' fails and when
|
||||
* other commands doing a merge do.
|
||||
*/
|
||||
advise("Fix them up in the work tree,");
|
||||
advise("and then use 'git add/rm <file>' as");
|
||||
advise("appropriate to mark resolution and make a commit,");
|
||||
advise("or use 'git commit -a'.");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void NORETURN die_resolve_conflict(const char *me)
|
||||
{
|
||||
error_resolve_conflict(me);
|
||||
die("Exiting because of an unresolved conflict.");
|
||||
die("'%s' is not possible because you have unmerged files.\n"
|
||||
"Please, fix them up in the work tree, and then use 'git add/rm <file>' as\n"
|
||||
"appropriate to mark resolution and make a commit, or use 'git commit -a'.", me);
|
||||
else
|
||||
die("'%s' is not possible because you have unmerged files.", me);
|
||||
}
|
||||
|
3
advice.h
3
advice.h
@ -11,8 +11,7 @@ extern int advice_implicit_identity;
|
||||
extern int advice_detached_head;
|
||||
|
||||
int git_default_advice_config(const char *var, const char *value);
|
||||
void advise(const char *advice, ...);
|
||||
int error_resolve_conflict(const char *me);
|
||||
|
||||
extern void NORETURN die_resolve_conflict(const char *me);
|
||||
|
||||
#endif /* ADVICE_H */
|
||||
|
135
archive-tar.c
135
archive-tar.c
@ -4,7 +4,6 @@
|
||||
#include "cache.h"
|
||||
#include "tar.h"
|
||||
#include "archive.h"
|
||||
#include "run-command.h"
|
||||
|
||||
#define RECORDSIZE (512)
|
||||
#define BLOCKSIZE (RECORDSIZE * 20)
|
||||
@ -14,9 +13,6 @@ static unsigned long offset;
|
||||
|
||||
static int tar_umask = 002;
|
||||
|
||||
static int write_tar_filter_archive(const struct archiver *ar,
|
||||
struct archiver_args *args);
|
||||
|
||||
/* writes out the whole block, but only if it is full */
|
||||
static void write_if_needed(void)
|
||||
{
|
||||
@ -224,67 +220,6 @@ static int write_global_extended_header(struct archiver_args *args)
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct archiver **tar_filters;
|
||||
static int nr_tar_filters;
|
||||
static int alloc_tar_filters;
|
||||
|
||||
static struct archiver *find_tar_filter(const char *name, int len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < nr_tar_filters; i++) {
|
||||
struct archiver *ar = tar_filters[i];
|
||||
if (!strncmp(ar->name, name, len) && !ar->name[len])
|
||||
return ar;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int tar_filter_config(const char *var, const char *value, void *data)
|
||||
{
|
||||
struct archiver *ar;
|
||||
const char *dot;
|
||||
const char *name;
|
||||
const char *type;
|
||||
int namelen;
|
||||
|
||||
if (prefixcmp(var, "tar."))
|
||||
return 0;
|
||||
dot = strrchr(var, '.');
|
||||
if (dot == var + 9)
|
||||
return 0;
|
||||
|
||||
name = var + 4;
|
||||
namelen = dot - name;
|
||||
type = dot + 1;
|
||||
|
||||
ar = find_tar_filter(name, namelen);
|
||||
if (!ar) {
|
||||
ar = xcalloc(1, sizeof(*ar));
|
||||
ar->name = xmemdupz(name, namelen);
|
||||
ar->write_archive = write_tar_filter_archive;
|
||||
ar->flags = ARCHIVER_WANT_COMPRESSION_LEVELS;
|
||||
ALLOC_GROW(tar_filters, nr_tar_filters + 1, alloc_tar_filters);
|
||||
tar_filters[nr_tar_filters++] = ar;
|
||||
}
|
||||
|
||||
if (!strcmp(type, "command")) {
|
||||
if (!value)
|
||||
return config_error_nonbool(var);
|
||||
free(ar->data);
|
||||
ar->data = xstrdup(value);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(type, "remote")) {
|
||||
if (git_config_bool(var, value))
|
||||
ar->flags |= ARCHIVER_REMOTE;
|
||||
else
|
||||
ar->flags &= ~ARCHIVER_REMOTE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int git_tar_config(const char *var, const char *value, void *cb)
|
||||
{
|
||||
if (!strcmp(var, "tar.umask")) {
|
||||
@ -296,15 +231,15 @@ static int git_tar_config(const char *var, const char *value, void *cb)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return tar_filter_config(var, value, cb);
|
||||
return git_default_config(var, value, cb);
|
||||
}
|
||||
|
||||
static int write_tar_archive(const struct archiver *ar,
|
||||
struct archiver_args *args)
|
||||
int write_tar_archive(struct archiver_args *args)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
git_config(git_tar_config, NULL);
|
||||
|
||||
if (args->commit_sha1)
|
||||
err = write_global_extended_header(args);
|
||||
if (!err)
|
||||
@ -313,65 +248,3 @@ static int write_tar_archive(const struct archiver *ar,
|
||||
write_trailer();
|
||||
return err;
|
||||
}
|
||||
|
||||
static int write_tar_filter_archive(const struct archiver *ar,
|
||||
struct archiver_args *args)
|
||||
{
|
||||
struct strbuf cmd = STRBUF_INIT;
|
||||
struct child_process filter;
|
||||
const char *argv[2];
|
||||
int r;
|
||||
|
||||
if (!ar->data)
|
||||
die("BUG: tar-filter archiver called with no filter defined");
|
||||
|
||||
strbuf_addstr(&cmd, ar->data);
|
||||
if (args->compression_level >= 0)
|
||||
strbuf_addf(&cmd, " -%d", args->compression_level);
|
||||
|
||||
memset(&filter, 0, sizeof(filter));
|
||||
argv[0] = cmd.buf;
|
||||
argv[1] = NULL;
|
||||
filter.argv = argv;
|
||||
filter.use_shell = 1;
|
||||
filter.in = -1;
|
||||
|
||||
if (start_command(&filter) < 0)
|
||||
die_errno("unable to start '%s' filter", argv[0]);
|
||||
close(1);
|
||||
if (dup2(filter.in, 1) < 0)
|
||||
die_errno("unable to redirect descriptor");
|
||||
close(filter.in);
|
||||
|
||||
r = write_tar_archive(ar, args);
|
||||
|
||||
close(1);
|
||||
if (finish_command(&filter) != 0)
|
||||
die("'%s' filter reported error", argv[0]);
|
||||
|
||||
strbuf_release(&cmd);
|
||||
return r;
|
||||
}
|
||||
|
||||
static struct archiver tar_archiver = {
|
||||
"tar",
|
||||
write_tar_archive,
|
||||
ARCHIVER_REMOTE
|
||||
};
|
||||
|
||||
void init_tar_archiver(void)
|
||||
{
|
||||
int i;
|
||||
register_archiver(&tar_archiver);
|
||||
|
||||
tar_filter_config("tar.tgz.command", "gzip -cn", NULL);
|
||||
tar_filter_config("tar.tgz.remote", "true", NULL);
|
||||
tar_filter_config("tar.tar.gz.command", "gzip -cn", NULL);
|
||||
tar_filter_config("tar.tar.gz.remote", "true", NULL);
|
||||
git_config(git_tar_config, NULL);
|
||||
for (i = 0; i < nr_tar_filters; i++) {
|
||||
/* omit any filters that never had a command configured */
|
||||
if (tar_filters[i]->data)
|
||||
register_archiver(tar_filters[i]);
|
||||
}
|
||||
}
|
||||
|
@ -261,8 +261,7 @@ static void dos_time(time_t *time, int *dos_date, int *dos_time)
|
||||
*dos_time = t->tm_sec / 2 + t->tm_min * 32 + t->tm_hour * 2048;
|
||||
}
|
||||
|
||||
static int write_zip_archive(const struct archiver *ar,
|
||||
struct archiver_args *args)
|
||||
int write_zip_archive(struct archiver_args *args)
|
||||
{
|
||||
int err;
|
||||
|
||||
@ -279,14 +278,3 @@ static int write_zip_archive(const struct archiver *ar,
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct archiver zip_archiver = {
|
||||
"zip",
|
||||
write_zip_archive,
|
||||
ARCHIVER_WANT_COMPRESSION_LEVELS|ARCHIVER_REMOTE
|
||||
};
|
||||
|
||||
void init_zip_archiver(void)
|
||||
{
|
||||
register_archiver(&zip_archiver);
|
||||
}
|
||||
|
96
archive.c
96
archive.c
@ -14,15 +14,16 @@ static char const * const archive_usage[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct archiver **archivers;
|
||||
static int nr_archivers;
|
||||
static int alloc_archivers;
|
||||
#define USES_ZLIB_COMPRESSION 1
|
||||
|
||||
void register_archiver(struct archiver *ar)
|
||||
{
|
||||
ALLOC_GROW(archivers, nr_archivers + 1, alloc_archivers);
|
||||
archivers[nr_archivers++] = ar;
|
||||
}
|
||||
static const struct archiver {
|
||||
const char *name;
|
||||
write_archive_fn_t write_archive;
|
||||
unsigned int flags;
|
||||
} archivers[] = {
|
||||
{ "tar", write_tar_archive },
|
||||
{ "zip", write_zip_archive, USES_ZLIB_COMPRESSION },
|
||||
};
|
||||
|
||||
static void format_subst(const struct commit *commit,
|
||||
const char *src, size_t len,
|
||||
@ -123,7 +124,7 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
|
||||
path_without_prefix = path.buf + args->baselen;
|
||||
|
||||
setup_archive_check(check);
|
||||
if (!git_check_attr(path_without_prefix, ARRAY_SIZE(check), check)) {
|
||||
if (!git_checkattr(path_without_prefix, ARRAY_SIZE(check), check)) {
|
||||
if (ATTR_TRUE(check[0].value))
|
||||
return 0;
|
||||
convert = ATTR_TRUE(check[1].value);
|
||||
@ -207,9 +208,9 @@ static const struct archiver *lookup_archiver(const char *name)
|
||||
if (!name)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < nr_archivers; i++) {
|
||||
if (!strcmp(name, archivers[i]->name))
|
||||
return archivers[i];
|
||||
for (i = 0; i < ARRAY_SIZE(archivers); i++) {
|
||||
if (!strcmp(name, archivers[i].name))
|
||||
return &archivers[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -298,10 +299,9 @@ static void parse_treeish_arg(const char **argv,
|
||||
PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_HIDDEN, NULL, (p) }
|
||||
|
||||
static int parse_archive_args(int argc, const char **argv,
|
||||
const struct archiver **ar, struct archiver_args *args,
|
||||
const char *name_hint, int is_remote)
|
||||
const struct archiver **ar, struct archiver_args *args)
|
||||
{
|
||||
const char *format = NULL;
|
||||
const char *format = "tar";
|
||||
const char *base = NULL;
|
||||
const char *remote = NULL;
|
||||
const char *exec = NULL;
|
||||
@ -318,7 +318,7 @@ static int parse_archive_args(int argc, const char **argv,
|
||||
"prepend prefix to each pathname in the archive"),
|
||||
OPT_STRING('o', "output", &output, "file",
|
||||
"write the archive to this file"),
|
||||
OPT_BOOL(0, "worktree-attributes", &worktree_attributes,
|
||||
OPT_BOOLEAN(0, "worktree-attributes", &worktree_attributes,
|
||||
"read .gitattributes in working directory"),
|
||||
OPT__VERBOSE(&verbose, "report archived files on stderr"),
|
||||
OPT__COMPR('0', &compression_level, "store only", 0),
|
||||
@ -332,7 +332,7 @@ static int parse_archive_args(int argc, const char **argv,
|
||||
OPT__COMPR_HIDDEN('8', &compression_level, 8),
|
||||
OPT__COMPR('9', &compression_level, "compress better", 9),
|
||||
OPT_GROUP(""),
|
||||
OPT_BOOL('l', "list", &list,
|
||||
OPT_BOOLEAN('l', "list", &list,
|
||||
"list supported archive formats"),
|
||||
OPT_GROUP(""),
|
||||
OPT_STRING(0, "remote", &remote, "repo",
|
||||
@ -355,27 +355,21 @@ static int parse_archive_args(int argc, const char **argv,
|
||||
base = "";
|
||||
|
||||
if (list) {
|
||||
for (i = 0; i < nr_archivers; i++)
|
||||
if (!is_remote || archivers[i]->flags & ARCHIVER_REMOTE)
|
||||
printf("%s\n", archivers[i]->name);
|
||||
for (i = 0; i < ARRAY_SIZE(archivers); i++)
|
||||
printf("%s\n", archivers[i].name);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (!format && name_hint)
|
||||
format = archive_format_from_filename(name_hint);
|
||||
if (!format)
|
||||
format = "tar";
|
||||
|
||||
/* We need at least one parameter -- tree-ish */
|
||||
if (argc < 1)
|
||||
usage_with_options(archive_usage, opts);
|
||||
*ar = lookup_archiver(format);
|
||||
if (!*ar || (is_remote && !((*ar)->flags & ARCHIVER_REMOTE)))
|
||||
if (!*ar)
|
||||
die("Unknown archive format '%s'", format);
|
||||
|
||||
args->compression_level = Z_DEFAULT_COMPRESSION;
|
||||
if (compression_level != -1) {
|
||||
if ((*ar)->flags & ARCHIVER_WANT_COMPRESSION_LEVELS)
|
||||
if ((*ar)->flags & USES_ZLIB_COMPRESSION)
|
||||
args->compression_level = compression_level;
|
||||
else {
|
||||
die("Argument not supported for format '%s': -%d",
|
||||
@ -391,55 +385,19 @@ static int parse_archive_args(int argc, const char **argv,
|
||||
}
|
||||
|
||||
int write_archive(int argc, const char **argv, const char *prefix,
|
||||
int setup_prefix, const char *name_hint, int remote)
|
||||
int setup_prefix)
|
||||
{
|
||||
int nongit = 0;
|
||||
const struct archiver *ar = NULL;
|
||||
struct archiver_args args;
|
||||
|
||||
argc = parse_archive_args(argc, argv, &ar, &args);
|
||||
if (setup_prefix && prefix == NULL)
|
||||
prefix = setup_git_directory_gently(&nongit);
|
||||
|
||||
git_config(git_default_config, NULL);
|
||||
init_tar_archiver();
|
||||
init_zip_archiver();
|
||||
|
||||
argc = parse_archive_args(argc, argv, &ar, &args, name_hint, remote);
|
||||
if (nongit) {
|
||||
/*
|
||||
* We know this will die() with an error, so we could just
|
||||
* die ourselves; but its error message will be more specific
|
||||
* than what we could write here.
|
||||
*/
|
||||
setup_git_directory();
|
||||
}
|
||||
prefix = setup_git_directory();
|
||||
|
||||
parse_treeish_arg(argv, &args, prefix);
|
||||
parse_pathspec_arg(argv + 1, &args);
|
||||
|
||||
return ar->write_archive(ar, &args);
|
||||
}
|
||||
|
||||
static int match_extension(const char *filename, const char *ext)
|
||||
{
|
||||
int prefixlen = strlen(filename) - strlen(ext);
|
||||
|
||||
/*
|
||||
* We need 1 character for the '.', and 1 character to ensure that the
|
||||
* prefix is non-empty (k.e., we don't match .tar.gz with no actual
|
||||
* filename).
|
||||
*/
|
||||
if (prefixlen < 2 || filename[prefixlen-1] != '.')
|
||||
return 0;
|
||||
return !strcmp(filename + prefixlen, ext);
|
||||
}
|
||||
|
||||
const char *archive_format_from_filename(const char *filename)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nr_archivers; i++)
|
||||
if (match_extension(filename, archivers[i]->name))
|
||||
return archivers[i]->name;
|
||||
return NULL;
|
||||
git_config(git_default_config, NULL);
|
||||
|
||||
return ar->write_archive(&args);
|
||||
}
|
||||
|
23
archive.h
23
archive.h
@ -14,24 +14,17 @@ struct archiver_args {
|
||||
int compression_level;
|
||||
};
|
||||
|
||||
#define ARCHIVER_WANT_COMPRESSION_LEVELS 1
|
||||
#define ARCHIVER_REMOTE 2
|
||||
struct archiver {
|
||||
const char *name;
|
||||
int (*write_archive)(const struct archiver *, struct archiver_args *);
|
||||
unsigned flags;
|
||||
void *data;
|
||||
};
|
||||
extern void register_archiver(struct archiver *);
|
||||
|
||||
extern void init_tar_archiver(void);
|
||||
extern void init_zip_archiver(void);
|
||||
typedef int (*write_archive_fn_t)(struct archiver_args *);
|
||||
|
||||
typedef int (*write_archive_entry_fn_t)(struct archiver_args *args, const unsigned char *sha1, const char *path, size_t pathlen, unsigned int mode, void *buffer, unsigned long size);
|
||||
|
||||
extern int write_archive_entries(struct archiver_args *args, write_archive_entry_fn_t write_entry);
|
||||
extern int write_archive(int argc, const char **argv, const char *prefix, int setup_prefix, const char *name_hint, int remote);
|
||||
/*
|
||||
* Archive-format specific backends.
|
||||
*/
|
||||
extern int write_tar_archive(struct archiver_args *);
|
||||
extern int write_zip_archive(struct archiver_args *);
|
||||
|
||||
const char *archive_format_from_filename(const char *filename);
|
||||
extern int write_archive_entries(struct archiver_args *args, write_archive_entry_fn_t write_entry);
|
||||
extern int write_archive(int argc, const char **argv, const char *prefix, int setup_prefix);
|
||||
|
||||
#endif /* ARCHIVE_H */
|
||||
|
51
argv-array.c
51
argv-array.c
@ -1,51 +0,0 @@
|
||||
#include "cache.h"
|
||||
#include "argv-array.h"
|
||||
#include "strbuf.h"
|
||||
|
||||
static const char *empty_argv_storage = NULL;
|
||||
const char **empty_argv = &empty_argv_storage;
|
||||
|
||||
void argv_array_init(struct argv_array *array)
|
||||
{
|
||||
array->argv = empty_argv;
|
||||
array->argc = 0;
|
||||
array->alloc = 0;
|
||||
}
|
||||
|
||||
static void argv_array_push_nodup(struct argv_array *array, const char *value)
|
||||
{
|
||||
if (array->argv == empty_argv)
|
||||
array->argv = NULL;
|
||||
|
||||
ALLOC_GROW(array->argv, array->argc + 2, array->alloc);
|
||||
array->argv[array->argc++] = value;
|
||||
array->argv[array->argc] = NULL;
|
||||
}
|
||||
|
||||
void argv_array_push(struct argv_array *array, const char *value)
|
||||
{
|
||||
argv_array_push_nodup(array, xstrdup(value));
|
||||
}
|
||||
|
||||
void argv_array_pushf(struct argv_array *array, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
struct strbuf v = STRBUF_INIT;
|
||||
|
||||
va_start(ap, fmt);
|
||||
strbuf_vaddf(&v, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
argv_array_push_nodup(array, strbuf_detach(&v, NULL));
|
||||
}
|
||||
|
||||
void argv_array_clear(struct argv_array *array)
|
||||
{
|
||||
if (array->argv != empty_argv) {
|
||||
int i;
|
||||
for (i = 0; i < array->argc; i++)
|
||||
free((char **)array->argv[i]);
|
||||
free(array->argv);
|
||||
}
|
||||
argv_array_init(array);
|
||||
}
|
20
argv-array.h
20
argv-array.h
@ -1,20 +0,0 @@
|
||||
#ifndef ARGV_ARRAY_H
|
||||
#define ARGV_ARRAY_H
|
||||
|
||||
extern const char **empty_argv;
|
||||
|
||||
struct argv_array {
|
||||
const char **argv;
|
||||
int argc;
|
||||
int alloc;
|
||||
};
|
||||
|
||||
#define ARGV_ARRAY_INIT { empty_argv, 0, 0 }
|
||||
|
||||
void argv_array_init(struct argv_array *);
|
||||
void argv_array_push(struct argv_array *, const char *);
|
||||
__attribute__((format (printf,2,3)))
|
||||
void argv_array_pushf(struct argv_array *, const char *fmt, ...);
|
||||
void argv_array_clear(struct argv_array *);
|
||||
|
||||
#endif /* ARGV_ARRAY_H */
|
330
attr.c
330
attr.c
@ -1,17 +1,7 @@
|
||||
/*
|
||||
* Handle git attributes. See gitattributes(5) for a description of
|
||||
* the file syntax, and Documentation/technical/api-gitattributes.txt
|
||||
* for a description of the API.
|
||||
*
|
||||
* One basic design decision here is that we are not going to support
|
||||
* an insanely large number of attributes.
|
||||
*/
|
||||
|
||||
#define NO_THE_INDEX_COMPATIBILITY_MACROS
|
||||
#include "cache.h"
|
||||
#include "exec_cmd.h"
|
||||
#include "attr.h"
|
||||
#include "dir.h"
|
||||
|
||||
const char git_attr__true[] = "(builtin)true";
|
||||
const char git_attr__false[] = "\0(builtin)false";
|
||||
@ -21,7 +11,14 @@ static const char git_attr__unknown[] = "(builtin)unknown";
|
||||
#define ATTR__UNSET NULL
|
||||
#define ATTR__UNKNOWN git_attr__unknown
|
||||
|
||||
/* This is a randomly chosen prime. */
|
||||
static const char *attributes_file;
|
||||
|
||||
/*
|
||||
* The basic design decision here is that we are not going to have
|
||||
* insanely large number of attributes.
|
||||
*
|
||||
* This is a randomly chosen prime.
|
||||
*/
|
||||
#define HASHSIZE 257
|
||||
|
||||
#ifndef DEBUG_ATTR
|
||||
@ -39,11 +36,6 @@ static int attr_nr;
|
||||
static struct git_attr_check *check_all_attr;
|
||||
static struct git_attr *(git_attr_hash[HASHSIZE]);
|
||||
|
||||
char *git_attr_name(struct git_attr *attr)
|
||||
{
|
||||
return attr->name;
|
||||
}
|
||||
|
||||
static unsigned hash_name(const char *name, int namelen)
|
||||
{
|
||||
unsigned val = 0, c;
|
||||
@ -58,10 +50,12 @@ static unsigned hash_name(const char *name, int namelen)
|
||||
static int invalid_attr_name(const char *name, int namelen)
|
||||
{
|
||||
/*
|
||||
* Attribute name cannot begin with '-' and must consist of
|
||||
* characters from [-A-Za-z0-9_.].
|
||||
* Attribute name cannot begin with '-' and from
|
||||
* [-A-Za-z0-9_.]. We'd specifically exclude '=' for now,
|
||||
* as we might later want to allow non-binary value for
|
||||
* attributes, e.g. "*.svg merge=special-merge-program-for-svg"
|
||||
*/
|
||||
if (namelen <= 0 || *name == '-')
|
||||
if (*name == '-')
|
||||
return -1;
|
||||
while (namelen--) {
|
||||
char ch = *name++;
|
||||
@ -109,26 +103,22 @@ struct git_attr *git_attr(const char *name)
|
||||
return git_attr_internal(name, strlen(name));
|
||||
}
|
||||
|
||||
/*
|
||||
* .gitattributes file is one line per record, each of which is
|
||||
*
|
||||
* (1) glob pattern.
|
||||
* (2) whitespace
|
||||
* (3) whitespace separated list of attribute names, each of which
|
||||
* could be prefixed with '-' to mean "set to false", '!' to mean
|
||||
* "unset".
|
||||
*/
|
||||
|
||||
/* What does a matched pattern decide? */
|
||||
struct attr_state {
|
||||
struct git_attr *attr;
|
||||
const char *setto;
|
||||
};
|
||||
|
||||
/*
|
||||
* One rule, as from a .gitattributes file.
|
||||
*
|
||||
* If is_macro is true, then u.attr is a pointer to the git_attr being
|
||||
* defined.
|
||||
*
|
||||
* If is_macro is false, then u.pattern points at the filename pattern
|
||||
* to which the rule applies. (The memory pointed to is part of the
|
||||
* memory block allocated for the match_attr instance.)
|
||||
*
|
||||
* In either case, num_attr is the number of attributes affected by
|
||||
* this rule, and state is an array listing them. The attributes are
|
||||
* listed as they appear in the file (macros unexpanded).
|
||||
*/
|
||||
struct match_attr {
|
||||
union {
|
||||
char *pattern;
|
||||
@ -141,15 +131,8 @@ struct match_attr {
|
||||
|
||||
static const char blank[] = " \t\r\n";
|
||||
|
||||
/*
|
||||
* Parse a whitespace-delimited attribute state (i.e., "attr",
|
||||
* "-attr", "!attr", or "attr=value") from the string starting at src.
|
||||
* If e is not NULL, write the results to *e. Return a pointer to the
|
||||
* remainder of the string (with leading whitespace removed), or NULL
|
||||
* if there was an error.
|
||||
*/
|
||||
static const char *parse_attr(const char *src, int lineno, const char *cp,
|
||||
struct attr_state *e)
|
||||
int *num_attr, struct match_attr *res)
|
||||
{
|
||||
const char *ep, *equals;
|
||||
int len;
|
||||
@ -162,7 +145,7 @@ static const char *parse_attr(const char *src, int lineno, const char *cp,
|
||||
len = equals - cp;
|
||||
else
|
||||
len = ep - cp;
|
||||
if (!e) {
|
||||
if (!res) {
|
||||
if (*cp == '-' || *cp == '!') {
|
||||
cp++;
|
||||
len--;
|
||||
@ -174,6 +157,9 @@ static const char *parse_attr(const char *src, int lineno, const char *cp,
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
struct attr_state *e;
|
||||
|
||||
e = &(res->state[*num_attr]);
|
||||
if (*cp == '-' || *cp == '!') {
|
||||
e->setto = (*cp == '-') ? ATTR__FALSE : ATTR__UNSET;
|
||||
cp++;
|
||||
@ -186,6 +172,7 @@ static const char *parse_attr(const char *src, int lineno, const char *cp,
|
||||
}
|
||||
e->attr = git_attr_internal(cp, len);
|
||||
}
|
||||
(*num_attr)++;
|
||||
return ep + strspn(ep, blank);
|
||||
}
|
||||
|
||||
@ -193,9 +180,10 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
|
||||
int lineno, int macro_ok)
|
||||
{
|
||||
int namelen;
|
||||
int num_attr, i;
|
||||
const char *cp, *name, *states;
|
||||
int num_attr;
|
||||
const char *cp, *name;
|
||||
struct match_attr *res = NULL;
|
||||
int pass;
|
||||
int is_macro;
|
||||
|
||||
cp = line + strspn(line, blank);
|
||||
@ -224,35 +212,32 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
|
||||
else
|
||||
is_macro = 0;
|
||||
|
||||
states = name + namelen;
|
||||
states += strspn(states, blank);
|
||||
|
||||
/* First pass to count the attr_states */
|
||||
for (cp = states, num_attr = 0; *cp; num_attr++) {
|
||||
cp = parse_attr(src, lineno, cp, NULL);
|
||||
if (!cp)
|
||||
return NULL;
|
||||
for (pass = 0; pass < 2; pass++) {
|
||||
/* pass 0 counts and allocates, pass 1 fills */
|
||||
num_attr = 0;
|
||||
cp = name + namelen;
|
||||
cp = cp + strspn(cp, blank);
|
||||
while (*cp) {
|
||||
cp = parse_attr(src, lineno, cp, &num_attr, res);
|
||||
if (!cp)
|
||||
return NULL;
|
||||
}
|
||||
if (pass)
|
||||
break;
|
||||
res = xcalloc(1,
|
||||
sizeof(*res) +
|
||||
sizeof(struct attr_state) * num_attr +
|
||||
(is_macro ? 0 : namelen + 1));
|
||||
if (is_macro)
|
||||
res->u.attr = git_attr_internal(name, namelen);
|
||||
else {
|
||||
res->u.pattern = (char *)&(res->state[num_attr]);
|
||||
memcpy(res->u.pattern, name, namelen);
|
||||
res->u.pattern[namelen] = 0;
|
||||
}
|
||||
res->is_macro = is_macro;
|
||||
res->num_attr = num_attr;
|
||||
}
|
||||
|
||||
res = xcalloc(1,
|
||||
sizeof(*res) +
|
||||
sizeof(struct attr_state) * num_attr +
|
||||
(is_macro ? 0 : namelen + 1));
|
||||
if (is_macro)
|
||||
res->u.attr = git_attr_internal(name, namelen);
|
||||
else {
|
||||
res->u.pattern = (char *)&(res->state[num_attr]);
|
||||
memcpy(res->u.pattern, name, namelen);
|
||||
res->u.pattern[namelen] = 0;
|
||||
}
|
||||
res->is_macro = is_macro;
|
||||
res->num_attr = num_attr;
|
||||
|
||||
/* Second pass to fill the attr_states */
|
||||
for (cp = states, i = 0; *cp; i++) {
|
||||
cp = parse_attr(src, lineno, cp, &(res->state[i]));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -301,6 +286,7 @@ static void free_attr_elem(struct attr_stack *e)
|
||||
}
|
||||
free(a);
|
||||
}
|
||||
free(e->attrs);
|
||||
free(e);
|
||||
}
|
||||
|
||||
@ -493,62 +479,68 @@ static int git_attr_system(void)
|
||||
return !git_env_bool("GIT_ATTR_NOSYSTEM", 0);
|
||||
}
|
||||
|
||||
static void bootstrap_attr_stack(void)
|
||||
static int git_attr_config(const char *var, const char *value, void *dummy)
|
||||
{
|
||||
if (!attr_stack) {
|
||||
struct attr_stack *elem;
|
||||
if (!strcmp(var, "core.attributesfile"))
|
||||
return git_config_pathname(&attributes_file, var, value);
|
||||
|
||||
elem = read_attr_from_array(builtin_attr);
|
||||
elem->origin = NULL;
|
||||
elem->prev = attr_stack;
|
||||
attr_stack = elem;
|
||||
|
||||
if (git_attr_system()) {
|
||||
elem = read_attr_from_file(git_etc_gitattributes(), 1);
|
||||
if (elem) {
|
||||
elem->origin = NULL;
|
||||
elem->prev = attr_stack;
|
||||
attr_stack = elem;
|
||||
}
|
||||
}
|
||||
|
||||
if (git_attributes_file) {
|
||||
elem = read_attr_from_file(git_attributes_file, 1);
|
||||
if (elem) {
|
||||
elem->origin = NULL;
|
||||
elem->prev = attr_stack;
|
||||
attr_stack = elem;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_bare_repository() || direction == GIT_ATTR_INDEX) {
|
||||
elem = read_attr(GITATTRIBUTES_FILE, 1);
|
||||
elem->origin = xstrdup("");
|
||||
elem->prev = attr_stack;
|
||||
attr_stack = elem;
|
||||
debug_push(elem);
|
||||
}
|
||||
|
||||
elem = read_attr_from_file(git_path(INFOATTRIBUTES_FILE), 1);
|
||||
if (!elem)
|
||||
elem = xcalloc(1, sizeof(*elem));
|
||||
elem->origin = NULL;
|
||||
elem->prev = attr_stack;
|
||||
attr_stack = elem;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void prepare_attr_stack(const char *path)
|
||||
static void bootstrap_attr_stack(void)
|
||||
{
|
||||
struct attr_stack *elem;
|
||||
|
||||
if (attr_stack)
|
||||
return;
|
||||
|
||||
elem = read_attr_from_array(builtin_attr);
|
||||
elem->origin = NULL;
|
||||
elem->prev = attr_stack;
|
||||
attr_stack = elem;
|
||||
|
||||
if (git_attr_system()) {
|
||||
elem = read_attr_from_file(git_etc_gitattributes(), 1);
|
||||
if (elem) {
|
||||
elem->origin = NULL;
|
||||
elem->prev = attr_stack;
|
||||
attr_stack = elem;
|
||||
}
|
||||
}
|
||||
|
||||
git_config(git_attr_config, NULL);
|
||||
if (attributes_file) {
|
||||
elem = read_attr_from_file(attributes_file, 1);
|
||||
if (elem) {
|
||||
elem->origin = NULL;
|
||||
elem->prev = attr_stack;
|
||||
attr_stack = elem;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_bare_repository() || direction == GIT_ATTR_INDEX) {
|
||||
elem = read_attr(GITATTRIBUTES_FILE, 1);
|
||||
elem->origin = strdup("");
|
||||
elem->prev = attr_stack;
|
||||
attr_stack = elem;
|
||||
debug_push(elem);
|
||||
}
|
||||
|
||||
elem = read_attr_from_file(git_path(INFOATTRIBUTES_FILE), 1);
|
||||
if (!elem)
|
||||
elem = xcalloc(1, sizeof(*elem));
|
||||
elem->origin = NULL;
|
||||
elem->prev = attr_stack;
|
||||
attr_stack = elem;
|
||||
}
|
||||
|
||||
static void prepare_attr_stack(const char *path, int dirlen)
|
||||
{
|
||||
struct attr_stack *elem, *info;
|
||||
int dirlen, len;
|
||||
const char *cp;
|
||||
int len;
|
||||
struct strbuf pathbuf;
|
||||
|
||||
cp = strrchr(path, '/');
|
||||
if (!cp)
|
||||
dirlen = 0;
|
||||
else
|
||||
dirlen = cp - path;
|
||||
strbuf_init(&pathbuf, dirlen+2+strlen(GITATTRIBUTES_FILE));
|
||||
|
||||
/*
|
||||
* At the bottom of the attribute stack is the built-in
|
||||
@ -565,7 +557,8 @@ static void prepare_attr_stack(const char *path)
|
||||
* .gitattributes in deeper directories to shallower ones,
|
||||
* and finally use the built-in set as the default.
|
||||
*/
|
||||
bootstrap_attr_stack();
|
||||
if (!attr_stack)
|
||||
bootstrap_attr_stack();
|
||||
|
||||
/*
|
||||
* Pop the "info" one that is always at the top of the stack.
|
||||
@ -575,14 +568,17 @@ static void prepare_attr_stack(const char *path)
|
||||
|
||||
/*
|
||||
* Pop the ones from directories that are not the prefix of
|
||||
* the path we are checking.
|
||||
* the path we are checking. Break out of the loop when we see
|
||||
* the root one (whose origin is an empty string "") or the builtin
|
||||
* one (whose origin is NULL) without popping it.
|
||||
*/
|
||||
while (attr_stack && attr_stack->origin) {
|
||||
while (attr_stack->origin) {
|
||||
int namelen = strlen(attr_stack->origin);
|
||||
|
||||
elem = attr_stack;
|
||||
if (namelen <= dirlen &&
|
||||
!strncmp(elem->origin, path, namelen))
|
||||
!strncmp(elem->origin, path, namelen) &&
|
||||
(!namelen || path[namelen] == '/'))
|
||||
break;
|
||||
|
||||
debug_pop(elem);
|
||||
@ -594,29 +590,35 @@ static void prepare_attr_stack(const char *path)
|
||||
* Read from parent directories and push them down
|
||||
*/
|
||||
if (!is_bare_repository() || direction == GIT_ATTR_INDEX) {
|
||||
struct strbuf pathbuf = STRBUF_INIT;
|
||||
|
||||
/*
|
||||
* bootstrap_attr_stack() should have added, and the
|
||||
* above loop should have stopped before popping, the
|
||||
* root element whose attr_stack->origin is set to an
|
||||
* empty string.
|
||||
*/
|
||||
assert(attr_stack->origin);
|
||||
while (1) {
|
||||
char *cp;
|
||||
|
||||
len = strlen(attr_stack->origin);
|
||||
if (dirlen <= len)
|
||||
break;
|
||||
cp = memchr(path + len + 1, '/', dirlen - len - 1);
|
||||
if (!cp)
|
||||
cp = path + dirlen;
|
||||
strbuf_add(&pathbuf, path, cp - path);
|
||||
strbuf_reset(&pathbuf);
|
||||
strbuf_add(&pathbuf, path, dirlen);
|
||||
strbuf_addch(&pathbuf, '/');
|
||||
strbuf_addstr(&pathbuf, GITATTRIBUTES_FILE);
|
||||
cp = strchr(pathbuf.buf + len + 1, '/');
|
||||
strcpy(cp + 1, GITATTRIBUTES_FILE);
|
||||
elem = read_attr(pathbuf.buf, 0);
|
||||
strbuf_setlen(&pathbuf, cp - path);
|
||||
elem->origin = strbuf_detach(&pathbuf, NULL);
|
||||
*cp = '\0';
|
||||
elem->origin = strdup(pathbuf.buf);
|
||||
elem->prev = attr_stack;
|
||||
attr_stack = elem;
|
||||
debug_push(elem);
|
||||
}
|
||||
|
||||
strbuf_release(&pathbuf);
|
||||
}
|
||||
|
||||
strbuf_release(&pathbuf);
|
||||
|
||||
/*
|
||||
* Finally push the "info" one at the top of the stack.
|
||||
*/
|
||||
@ -632,7 +634,7 @@ static int path_matches(const char *pathname, int pathlen,
|
||||
/* match basename */
|
||||
const char *basename = strrchr(pathname, '/');
|
||||
basename = basename ? basename + 1 : pathname;
|
||||
return (fnmatch_icase(pattern, basename, 0) == 0);
|
||||
return (fnmatch(pattern, basename, 0) == 0);
|
||||
}
|
||||
/*
|
||||
* match with FNM_PATHNAME; the pattern has base implicitly
|
||||
@ -646,7 +648,7 @@ static int path_matches(const char *pathname, int pathlen,
|
||||
return 0;
|
||||
if (baselen != 0)
|
||||
baselen++;
|
||||
return fnmatch_icase(pattern, pathname + baselen, FNM_PATHNAME) == 0;
|
||||
return fnmatch(pattern, pathname + baselen, FNM_PATHNAME) == 0;
|
||||
}
|
||||
|
||||
static int macroexpand_one(int attr_nr, int rem);
|
||||
@ -713,30 +715,26 @@ static int macroexpand_one(int attr_nr, int rem)
|
||||
return rem;
|
||||
}
|
||||
|
||||
/*
|
||||
* Collect all attributes for path into the array pointed to by
|
||||
* check_all_attr.
|
||||
*/
|
||||
static void collect_all_attrs(const char *path)
|
||||
int git_checkattr(const char *path, int num, struct git_attr_check *check)
|
||||
{
|
||||
struct attr_stack *stk;
|
||||
int i, pathlen, rem;
|
||||
const char *cp;
|
||||
int dirlen, pathlen, i, rem;
|
||||
|
||||
prepare_attr_stack(path);
|
||||
bootstrap_attr_stack();
|
||||
for (i = 0; i < attr_nr; i++)
|
||||
check_all_attr[i].value = ATTR__UNKNOWN;
|
||||
|
||||
pathlen = strlen(path);
|
||||
cp = strrchr(path, '/');
|
||||
if (!cp)
|
||||
dirlen = 0;
|
||||
else
|
||||
dirlen = cp - path;
|
||||
prepare_attr_stack(path, dirlen);
|
||||
rem = attr_nr;
|
||||
for (stk = attr_stack; 0 < rem && stk; stk = stk->prev)
|
||||
rem = fill(path, pathlen, stk, rem);
|
||||
}
|
||||
|
||||
int git_check_attr(const char *path, int num, struct git_attr_check *check)
|
||||
{
|
||||
int i;
|
||||
|
||||
collect_all_attrs(path);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
const char *value = check_all_attr[check[i].attr->attr_nr].value;
|
||||
@ -748,34 +746,6 @@ int git_check_attr(const char *path, int num, struct git_attr_check *check)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_all_attrs(const char *path, int *num, struct git_attr_check **check)
|
||||
{
|
||||
int i, count, j;
|
||||
|
||||
collect_all_attrs(path);
|
||||
|
||||
/* Count the number of attributes that are set. */
|
||||
count = 0;
|
||||
for (i = 0; i < attr_nr; i++) {
|
||||
const char *value = check_all_attr[i].value;
|
||||
if (value != ATTR__UNSET && value != ATTR__UNKNOWN)
|
||||
++count;
|
||||
}
|
||||
*num = count;
|
||||
*check = xmalloc(sizeof(**check) * count);
|
||||
j = 0;
|
||||
for (i = 0; i < attr_nr; i++) {
|
||||
const char *value = check_all_attr[i].value;
|
||||
if (value != ATTR__UNSET && value != ATTR__UNKNOWN) {
|
||||
(*check)[j].attr = check_all_attr[i].attr;
|
||||
(*check)[j].value = value;
|
||||
++j;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void git_attr_set_direction(enum git_attr_direction new, struct index_state *istate)
|
||||
{
|
||||
enum git_attr_direction old = direction;
|
||||
|
20
attr.h
20
attr.h
@ -20,7 +20,7 @@ extern const char git_attr__false[];
|
||||
#define ATTR_UNSET(v) ((v) == NULL)
|
||||
|
||||
/*
|
||||
* Send one or more git_attr_check to git_check_attr(), and
|
||||
* Send one or more git_attr_check to git_checkattr(), and
|
||||
* each 'value' member tells what its value is.
|
||||
* Unset one is returned as NULL.
|
||||
*/
|
||||
@ -29,23 +29,7 @@ struct git_attr_check {
|
||||
const char *value;
|
||||
};
|
||||
|
||||
/*
|
||||
* Return the name of the attribute represented by the argument. The
|
||||
* return value is a pointer to a null-delimited string that is part
|
||||
* of the internal data structure; it should not be modified or freed.
|
||||
*/
|
||||
char *git_attr_name(struct git_attr *);
|
||||
|
||||
int git_check_attr(const char *path, int, struct git_attr_check *);
|
||||
|
||||
/*
|
||||
* Retrieve all attributes that apply to the specified path. *num
|
||||
* will be set the the number of attributes on the path; **check will
|
||||
* be set to point at a newly-allocated array of git_attr_check
|
||||
* objects describing the attributes and their values. *check must be
|
||||
* free()ed by the caller.
|
||||
*/
|
||||
int git_all_attrs(const char *path, int *num, struct git_attr_check **check);
|
||||
int git_checkattr(const char *path, int, struct git_attr_check *);
|
||||
|
||||
enum git_attr_direction {
|
||||
GIT_ATTR_CHECKIN,
|
||||
|
101
bisect.c
101
bisect.c
@ -10,16 +10,20 @@
|
||||
#include "log-tree.h"
|
||||
#include "bisect.h"
|
||||
#include "sha1-array.h"
|
||||
#include "argv-array.h"
|
||||
|
||||
static struct sha1_array good_revs;
|
||||
static struct sha1_array skipped_revs;
|
||||
|
||||
static const unsigned char *current_bad_sha1;
|
||||
|
||||
struct argv_array {
|
||||
const char **argv;
|
||||
int argv_nr;
|
||||
int argv_alloc;
|
||||
};
|
||||
|
||||
static const char *argv_checkout[] = {"checkout", "-q", NULL, "--", NULL};
|
||||
static const char *argv_show_branch[] = {"show-branch", NULL, NULL};
|
||||
static const char *argv_update_ref[] = {"update-ref", "--no-deref", "BISECT_HEAD", NULL, NULL};
|
||||
|
||||
/* bits #0-15 in revision.h */
|
||||
|
||||
@ -400,6 +404,21 @@ struct commit_list *find_bisection(struct commit_list *list,
|
||||
return best;
|
||||
}
|
||||
|
||||
static void argv_array_push(struct argv_array *array, const char *string)
|
||||
{
|
||||
ALLOC_GROW(array->argv, array->argv_nr + 1, array->argv_alloc);
|
||||
array->argv[array->argv_nr++] = string;
|
||||
}
|
||||
|
||||
static void argv_array_push_sha1(struct argv_array *array,
|
||||
const unsigned char *sha1,
|
||||
const char *format)
|
||||
{
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
strbuf_addf(&buf, format, sha1_to_hex(sha1));
|
||||
argv_array_push(array, strbuf_detach(&buf, NULL));
|
||||
}
|
||||
|
||||
static int register_ref(const char *refname, const unsigned char *sha1,
|
||||
int flags, void *cb_data)
|
||||
{
|
||||
@ -429,10 +448,16 @@ static void read_bisect_paths(struct argv_array *array)
|
||||
die_errno("Could not open file '%s'", filename);
|
||||
|
||||
while (strbuf_getline(&str, fp, '\n') != EOF) {
|
||||
char *quoted;
|
||||
int res;
|
||||
|
||||
strbuf_trim(&str);
|
||||
if (sq_dequote_to_argv_array(str.buf, array))
|
||||
quoted = strbuf_detach(&str, NULL);
|
||||
res = sq_dequote_to_argv(quoted, &array->argv,
|
||||
&array->argv_nr, &array->argv_alloc);
|
||||
if (res)
|
||||
die("Badly quoted content in file '%s': %s",
|
||||
filename, str.buf);
|
||||
filename, quoted);
|
||||
}
|
||||
|
||||
strbuf_release(&str);
|
||||
@ -597,7 +622,7 @@ static void bisect_rev_setup(struct rev_info *revs, const char *prefix,
|
||||
const char *bad_format, const char *good_format,
|
||||
int read_paths)
|
||||
{
|
||||
struct argv_array rev_argv = ARGV_ARRAY_INIT;
|
||||
struct argv_array rev_argv = { NULL, 0, 0 };
|
||||
int i;
|
||||
|
||||
init_revisions(revs, prefix);
|
||||
@ -605,17 +630,17 @@ static void bisect_rev_setup(struct rev_info *revs, const char *prefix,
|
||||
revs->commit_format = CMIT_FMT_UNSPECIFIED;
|
||||
|
||||
/* rev_argv.argv[0] will be ignored by setup_revisions */
|
||||
argv_array_push(&rev_argv, "bisect_rev_setup");
|
||||
argv_array_pushf(&rev_argv, bad_format, sha1_to_hex(current_bad_sha1));
|
||||
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.nr; i++)
|
||||
argv_array_pushf(&rev_argv, good_format,
|
||||
sha1_to_hex(good_revs.sha1[i]));
|
||||
argv_array_push(&rev_argv, "--");
|
||||
argv_array_push_sha1(&rev_argv, good_revs.sha1[i],
|
||||
good_format);
|
||||
argv_array_push(&rev_argv, xstrdup("--"));
|
||||
if (read_paths)
|
||||
read_bisect_paths(&rev_argv);
|
||||
argv_array_push(&rev_argv, NULL);
|
||||
|
||||
setup_revisions(rev_argv.argc, rev_argv.argv, revs, NULL);
|
||||
/* XXX leak rev_argv, as "revs" may still be pointing to it */
|
||||
setup_revisions(rev_argv.argv_nr, rev_argv.argv, revs, NULL);
|
||||
}
|
||||
|
||||
static void bisect_common(struct rev_info *revs)
|
||||
@ -682,23 +707,16 @@ static void mark_expected_rev(char *bisect_rev_hex)
|
||||
die("closing file %s: %s", filename, strerror(errno));
|
||||
}
|
||||
|
||||
static int bisect_checkout(char *bisect_rev_hex, int no_checkout)
|
||||
static int bisect_checkout(char *bisect_rev_hex)
|
||||
{
|
||||
int res;
|
||||
|
||||
mark_expected_rev(bisect_rev_hex);
|
||||
|
||||
argv_checkout[2] = bisect_rev_hex;
|
||||
if (no_checkout) {
|
||||
argv_update_ref[3] = bisect_rev_hex;
|
||||
if (run_command_v_opt(argv_update_ref, RUN_GIT_CMD))
|
||||
die("update-ref --no-deref HEAD failed on %s",
|
||||
bisect_rev_hex);
|
||||
} else {
|
||||
res = run_command_v_opt(argv_checkout, RUN_GIT_CMD);
|
||||
if (res)
|
||||
exit(res);
|
||||
}
|
||||
res = run_command_v_opt(argv_checkout, RUN_GIT_CMD);
|
||||
if (res)
|
||||
exit(res);
|
||||
|
||||
argv_show_branch[1] = bisect_rev_hex;
|
||||
return run_command_v_opt(argv_show_branch, RUN_GIT_CMD);
|
||||
@ -770,7 +788,7 @@ static void handle_skipped_merge_base(const unsigned char *mb)
|
||||
* - If one is "skipped", we can't know but we should warn.
|
||||
* - If we don't know, we should check it out and ask the user to test.
|
||||
*/
|
||||
static void check_merge_bases(int no_checkout)
|
||||
static void check_merge_bases(void)
|
||||
{
|
||||
struct commit_list *result;
|
||||
int rev_nr;
|
||||
@ -788,7 +806,7 @@ static void check_merge_bases(int no_checkout)
|
||||
handle_skipped_merge_base(mb);
|
||||
} else {
|
||||
printf("Bisecting: a merge base must be tested\n");
|
||||
exit(bisect_checkout(sha1_to_hex(mb), no_checkout));
|
||||
exit(bisect_checkout(sha1_to_hex(mb)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -800,25 +818,25 @@ static int check_ancestors(const char *prefix)
|
||||
{
|
||||
struct rev_info revs;
|
||||
struct object_array pending_copy;
|
||||
int res;
|
||||
int i, res;
|
||||
|
||||
bisect_rev_setup(&revs, prefix, "^%s", "%s", 0);
|
||||
|
||||
/* Save pending objects, so they can be cleaned up later. */
|
||||
pending_copy = revs.pending;
|
||||
revs.leak_pending = 1;
|
||||
memset(&pending_copy, 0, sizeof(pending_copy));
|
||||
for (i = 0; i < revs.pending.nr; i++)
|
||||
add_object_array(revs.pending.objects[i].item,
|
||||
revs.pending.objects[i].name,
|
||||
&pending_copy);
|
||||
|
||||
/*
|
||||
* bisect_common calls prepare_revision_walk right away, which
|
||||
* (together with .leak_pending = 1) makes us the sole owner of
|
||||
* the list of pending objects.
|
||||
*/
|
||||
bisect_common(&revs);
|
||||
res = (revs.commits != NULL);
|
||||
|
||||
/* Clean up objects used, as they will be reused. */
|
||||
clear_commit_marks_for_object_array(&pending_copy, ALL_REV_FLAGS);
|
||||
free(pending_copy.objects);
|
||||
for (i = 0; i < pending_copy.nr; i++) {
|
||||
struct object *o = pending_copy.objects[i].item;
|
||||
clear_commit_marks((struct commit *)o, ALL_REV_FLAGS);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -831,7 +849,7 @@ static int check_ancestors(const char *prefix)
|
||||
* If a merge base must be tested by the user, its source code will be
|
||||
* checked out to be tested by the user and we will exit.
|
||||
*/
|
||||
static void check_good_are_ancestors_of_bad(const char *prefix, int no_checkout)
|
||||
static void check_good_are_ancestors_of_bad(const char *prefix)
|
||||
{
|
||||
const char *filename = git_path("BISECT_ANCESTORS_OK");
|
||||
struct stat st;
|
||||
@ -850,7 +868,7 @@ static void check_good_are_ancestors_of_bad(const char *prefix, int no_checkout)
|
||||
|
||||
/* Check if all good revs are ancestor of the bad rev. */
|
||||
if (check_ancestors(prefix))
|
||||
check_merge_bases(no_checkout);
|
||||
check_merge_bases();
|
||||
|
||||
/* Create file BISECT_ANCESTORS_OK. */
|
||||
fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600);
|
||||
@ -890,11 +908,8 @@ static void show_diff_tree(const char *prefix, struct commit *commit)
|
||||
* We use the convention that exiting with an exit code 10 means that
|
||||
* the bisection process finished successfully.
|
||||
* In this case the calling shell script should exit 0.
|
||||
*
|
||||
* If no_checkout is non-zero, the bisection process does not
|
||||
* checkout the trial commit but instead simply updates BISECT_HEAD.
|
||||
*/
|
||||
int bisect_next_all(const char *prefix, int no_checkout)
|
||||
int bisect_next_all(const char *prefix)
|
||||
{
|
||||
struct rev_info revs;
|
||||
struct commit_list *tried;
|
||||
@ -905,7 +920,7 @@ int bisect_next_all(const char *prefix, int no_checkout)
|
||||
if (read_bisect_refs())
|
||||
die("reading bisect refs failed");
|
||||
|
||||
check_good_are_ancestors_of_bad(prefix, no_checkout);
|
||||
check_good_are_ancestors_of_bad(prefix);
|
||||
|
||||
bisect_rev_setup(&revs, prefix, "%s", "^%s", 1);
|
||||
revs.limited = 1;
|
||||
@ -951,6 +966,6 @@ int bisect_next_all(const char *prefix, int no_checkout)
|
||||
"(roughly %d step%s)\n", nr, (nr == 1 ? "" : "s"),
|
||||
steps, (steps == 1 ? "" : "s"));
|
||||
|
||||
return bisect_checkout(bisect_rev_hex, no_checkout);
|
||||
return bisect_checkout(bisect_rev_hex);
|
||||
}
|
||||
|
||||
|
2
bisect.h
2
bisect.h
@ -27,7 +27,7 @@ struct rev_list_info {
|
||||
const char *header_prefix;
|
||||
};
|
||||
|
||||
extern int bisect_next_all(const char *prefix, int no_checkout);
|
||||
extern int bisect_next_all(const char *prefix);
|
||||
|
||||
extern int estimate_bisect_steps(int all);
|
||||
|
||||
|
39
branch.c
39
branch.c
@ -3,7 +3,6 @@
|
||||
#include "refs.h"
|
||||
#include "remote.h"
|
||||
#include "commit.h"
|
||||
#include "sequencer.h"
|
||||
|
||||
struct tracking {
|
||||
struct refspec spec;
|
||||
@ -136,28 +135,6 @@ static int setup_tracking(const char *new_ref, const char *orig_ref,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int validate_new_branchname(const char *name, struct strbuf *ref,
|
||||
int force, int attr_only)
|
||||
{
|
||||
if (strbuf_check_branch_ref(ref, name))
|
||||
die("'%s' is not a valid branch name.", name);
|
||||
|
||||
if (!ref_exists(ref->buf))
|
||||
return 0;
|
||||
else if (!force && !attr_only)
|
||||
die("A branch named '%s' already exists.", ref->buf + strlen("refs/heads/"));
|
||||
|
||||
if (!attr_only) {
|
||||
const char *head;
|
||||
unsigned char sha1[20];
|
||||
|
||||
head = resolve_ref("HEAD", sha1, 0, NULL);
|
||||
if (!is_bare_repository() && head && !strcmp(head, ref->buf))
|
||||
die("Cannot force update the current branch.");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void create_branch(const char *head,
|
||||
const char *name, const char *start_name,
|
||||
int force, int reflog, enum branch_track track)
|
||||
@ -174,12 +151,17 @@ void create_branch(const char *head,
|
||||
if (track == BRANCH_TRACK_EXPLICIT || track == BRANCH_TRACK_OVERRIDE)
|
||||
explicit_tracking = 1;
|
||||
|
||||
if (validate_new_branchname(name, &ref, force,
|
||||
track == BRANCH_TRACK_OVERRIDE)) {
|
||||
if (!force)
|
||||
if (strbuf_check_branch_ref(&ref, name))
|
||||
die("'%s' is not a valid branch name.", name);
|
||||
|
||||
if (resolve_ref(ref.buf, sha1, 1, NULL)) {
|
||||
if (!force && track == BRANCH_TRACK_OVERRIDE)
|
||||
dont_change_ref = 1;
|
||||
else
|
||||
forcing = 1;
|
||||
else if (!force)
|
||||
die("A branch named '%s' already exists.", name);
|
||||
else if (!is_bare_repository() && head && !strcmp(head, name))
|
||||
die("Cannot force update the current branch.");
|
||||
forcing = 1;
|
||||
}
|
||||
|
||||
real_ref = NULL;
|
||||
@ -246,5 +228,4 @@ void remove_branch_state(void)
|
||||
unlink(git_path("MERGE_MSG"));
|
||||
unlink(git_path("MERGE_MODE"));
|
||||
unlink(git_path("SQUASH_MSG"));
|
||||
remove_sequencer_state(0);
|
||||
}
|
||||
|
18
branch.h
18
branch.h
@ -15,24 +15,6 @@
|
||||
void create_branch(const char *head, const char *name, const char *start_name,
|
||||
int force, int reflog, enum branch_track track);
|
||||
|
||||
/*
|
||||
* Validates that the requested branch may be created, returning the
|
||||
* interpreted ref in ref, force indicates whether (non-head) branches
|
||||
* may be overwritten. A non-zero return value indicates that the force
|
||||
* parameter was non-zero and the branch already exists.
|
||||
*
|
||||
* Contrary to all of the above, when attr_only is 1, the caller is
|
||||
* not interested in verifying if it is Ok to update the named
|
||||
* branch to point at a potentially different commit. It is merely
|
||||
* asking if it is OK to change some attribute for the named branch
|
||||
* (e.g. tracking upstream).
|
||||
*
|
||||
* NEEDSWORK: This needs to be split into two separate functions in the
|
||||
* longer run for sanity.
|
||||
*
|
||||
*/
|
||||
int validate_new_branchname(const char *name, struct strbuf *ref, int force, int attr_only);
|
||||
|
||||
/*
|
||||
* Remove information about the state of working on the current
|
||||
* branch. (E.g., MERGE_HEAD)
|
||||
|
@ -1407,9 +1407,6 @@ static int find_header(char *line, unsigned long size, int *hdrsize, struct patc
|
||||
"%d leading pathname components (line %d)" , p_value, linenr);
|
||||
patch->old_name = patch->new_name = patch->def_name;
|
||||
}
|
||||
if (!patch->is_delete && !patch->new_name)
|
||||
die("git diff header lacks filename information "
|
||||
"(line %d)", linenr);
|
||||
patch->is_toplevel_relative = 1;
|
||||
*hdrsize = git_hdr_len;
|
||||
return offset;
|
||||
@ -2450,8 +2447,6 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
|
||||
char *old, *oldlines;
|
||||
struct strbuf newlines;
|
||||
int new_blank_lines_at_end = 0;
|
||||
int found_new_blank_lines_at_end = 0;
|
||||
int hunk_linenr = frag->linenr;
|
||||
unsigned long leading, trailing;
|
||||
int pos, applied_pos;
|
||||
struct image preimage;
|
||||
@ -2545,18 +2540,14 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
|
||||
error("invalid start of line: '%c'", first);
|
||||
return -1;
|
||||
}
|
||||
if (added_blank_line) {
|
||||
if (!new_blank_lines_at_end)
|
||||
found_new_blank_lines_at_end = hunk_linenr;
|
||||
if (added_blank_line)
|
||||
new_blank_lines_at_end++;
|
||||
}
|
||||
else if (is_blank_context)
|
||||
;
|
||||
else
|
||||
new_blank_lines_at_end = 0;
|
||||
patch += len;
|
||||
size -= len;
|
||||
hunk_linenr++;
|
||||
}
|
||||
if (inaccurate_eof &&
|
||||
old > oldlines && old[-1] == '\n' &&
|
||||
@ -2638,8 +2629,7 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
|
||||
preimage.nr + applied_pos >= img->nr &&
|
||||
(ws_rule & WS_BLANK_AT_EOF) &&
|
||||
ws_error_action != nowarn_ws_error) {
|
||||
record_ws_error(WS_BLANK_AT_EOF, "+", 1,
|
||||
found_new_blank_lines_at_end);
|
||||
record_ws_error(WS_BLANK_AT_EOF, "+", 1, frag->linenr);
|
||||
if (ws_error_action == correct_ws_error) {
|
||||
while (new_blank_lines_at_end--)
|
||||
remove_last_line(&postimage);
|
||||
@ -3841,6 +3831,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)
|
||||
int i;
|
||||
int errs = 0;
|
||||
int is_not_gitdir = !startup_info->have_repository;
|
||||
int binary;
|
||||
int force_apply = 0;
|
||||
|
||||
const char *whitespace_option = NULL;
|
||||
@ -3859,8 +3850,12 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)
|
||||
"ignore additions made by the patch"),
|
||||
OPT_BOOLEAN(0, "stat", &diffstat,
|
||||
"instead of applying the patch, output diffstat for the input"),
|
||||
OPT_NOOP_NOARG(0, "allow-binary-replacement"),
|
||||
OPT_NOOP_NOARG(0, "binary"),
|
||||
{ OPTION_BOOLEAN, 0, "allow-binary-replacement", &binary,
|
||||
NULL, "old option, now no-op",
|
||||
PARSE_OPT_HIDDEN | PARSE_OPT_NOARG },
|
||||
{ OPTION_BOOLEAN, 0, "binary", &binary,
|
||||
NULL, "old option, now no-op",
|
||||
PARSE_OPT_HIDDEN | PARSE_OPT_NOARG },
|
||||
OPT_BOOLEAN(0, "numstat", &numstat,
|
||||
"shows number of added and deleted lines in decimal notation"),
|
||||
OPT_BOOLEAN(0, "summary", &summary,
|
||||
|
@ -24,8 +24,7 @@ static void create_output_file(const char *output_file)
|
||||
}
|
||||
|
||||
static int run_remote_archiver(int argc, const char **argv,
|
||||
const char *remote, const char *exec,
|
||||
const char *name_hint)
|
||||
const char *remote, const char *exec)
|
||||
{
|
||||
char buf[LARGE_PACKET_MAX];
|
||||
int fd[2], i, len, rv;
|
||||
@ -38,17 +37,6 @@ static int run_remote_archiver(int argc, const char **argv,
|
||||
transport = transport_get(_remote, _remote->url[0]);
|
||||
transport_connect(transport, "git-upload-archive", exec, fd);
|
||||
|
||||
/*
|
||||
* Inject a fake --format field at the beginning of the
|
||||
* arguments, with the format inferred from our output
|
||||
* filename. This way explicit --format options can override
|
||||
* it.
|
||||
*/
|
||||
if (name_hint) {
|
||||
const char *format = archive_format_from_filename(name_hint);
|
||||
if (format)
|
||||
packet_write(fd[1], "argument --format=%s\n", format);
|
||||
}
|
||||
for (i = 1; i < argc; i++)
|
||||
packet_write(fd[1], "argument %s\n", argv[i]);
|
||||
packet_flush(fd[1]);
|
||||
@ -61,8 +49,6 @@ static int run_remote_archiver(int argc, const char **argv,
|
||||
if (strcmp(buf, "ACK")) {
|
||||
if (len > 5 && !prefixcmp(buf, "NACK "))
|
||||
die(_("git archive: NACK %s"), buf + 5);
|
||||
if (len > 4 && !prefixcmp(buf, "ERR "))
|
||||
die(_("remote error: %s"), buf + 4);
|
||||
die(_("git archive: protocol error"));
|
||||
}
|
||||
|
||||
@ -77,6 +63,17 @@ static int run_remote_archiver(int argc, const char **argv,
|
||||
return !!rv;
|
||||
}
|
||||
|
||||
static const char *format_from_name(const char *filename)
|
||||
{
|
||||
const char *ext = strrchr(filename, '.');
|
||||
if (!ext)
|
||||
return NULL;
|
||||
ext++;
|
||||
if (!strcasecmp(ext, "zip"))
|
||||
return "--format=zip";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define PARSE_OPT_KEEP_ALL ( PARSE_OPT_KEEP_DASHDASH | \
|
||||
PARSE_OPT_KEEP_ARGV0 | \
|
||||
PARSE_OPT_KEEP_UNKNOWN | \
|
||||
@ -87,6 +84,7 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
|
||||
const char *exec = "git-upload-archive";
|
||||
const char *output = NULL;
|
||||
const char *remote = NULL;
|
||||
const char *format_option = NULL;
|
||||
struct option local_opts[] = {
|
||||
OPT_STRING('o', "output", &output, "file",
|
||||
"write the archive to this file"),
|
||||
@ -100,13 +98,32 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
|
||||
argc = parse_options(argc, argv, prefix, local_opts, NULL,
|
||||
PARSE_OPT_KEEP_ALL);
|
||||
|
||||
if (output)
|
||||
if (output) {
|
||||
create_output_file(output);
|
||||
format_option = format_from_name(output);
|
||||
}
|
||||
|
||||
/*
|
||||
* We have enough room in argv[] to muck it in place, because
|
||||
* --output must have been given on the original command line
|
||||
* if we get to this point, and parse_options() must have eaten
|
||||
* it, i.e. we can add back one element to the array.
|
||||
*
|
||||
* We add a fake --format option at the beginning, with the
|
||||
* format inferred from our output filename. This way explicit
|
||||
* --format options can override it, and the fake option is
|
||||
* inserted before any "--" that might have been given.
|
||||
*/
|
||||
if (format_option) {
|
||||
memmove(argv + 2, argv + 1, sizeof(*argv) * argc);
|
||||
argv[1] = format_option;
|
||||
argv[++argc] = NULL;
|
||||
}
|
||||
|
||||
if (remote)
|
||||
return run_remote_archiver(argc, argv, remote, exec, output);
|
||||
return run_remote_archiver(argc, argv, remote, exec);
|
||||
|
||||
setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
|
||||
|
||||
return write_archive(argc, argv, prefix, 1, output, 0);
|
||||
return write_archive(argc, argv, prefix, 1);
|
||||
}
|
||||
|
@ -4,19 +4,16 @@
|
||||
#include "bisect.h"
|
||||
|
||||
static const char * const git_bisect_helper_usage[] = {
|
||||
"git bisect--helper --next-all [--no-checkout]",
|
||||
"git bisect--helper --next-all",
|
||||
NULL
|
||||
};
|
||||
|
||||
int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int next_all = 0;
|
||||
int no_checkout = 0;
|
||||
struct option options[] = {
|
||||
OPT_BOOLEAN(0, "next-all", &next_all,
|
||||
"perform 'git bisect next'"),
|
||||
OPT_BOOLEAN(0, "no-checkout", &no_checkout,
|
||||
"update BISECT_HEAD instead of checking out the current commit"),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
@ -27,5 +24,5 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
|
||||
usage_with_options(git_bisect_helper_usage, options);
|
||||
|
||||
/* next-all */
|
||||
return bisect_next_all(prefix, no_checkout);
|
||||
return bisect_next_all(prefix);
|
||||
}
|
||||
|
@ -1598,7 +1598,7 @@ static const char *format_time(unsigned long time, const char *tz_str,
|
||||
int tz;
|
||||
|
||||
if (show_raw_time) {
|
||||
sprintf(time_buf, "%lu %s", time, tz_str);
|
||||
snprintf(time_buf, sizeof(time_buf), "%lu %s", time, tz_str);
|
||||
}
|
||||
else {
|
||||
tz = atoi(tz_str);
|
||||
|
@ -71,7 +71,7 @@ static int parse_branch_color_slot(const char *var, int ofs)
|
||||
static int git_branch_config(const char *var, const char *value, void *cb)
|
||||
{
|
||||
if (!strcmp(var, "color.branch")) {
|
||||
branch_use_color = git_config_colorbool(var, value);
|
||||
branch_use_color = git_config_colorbool(var, value, -1);
|
||||
return 0;
|
||||
}
|
||||
if (!prefixcmp(var, "color.branch.")) {
|
||||
@ -88,7 +88,7 @@ static int git_branch_config(const char *var, const char *value, void *cb)
|
||||
|
||||
static const char *branch_get_color(enum color_branch ix)
|
||||
{
|
||||
if (want_color(branch_use_color))
|
||||
if (branch_use_color > 0)
|
||||
return branch_colors[ix];
|
||||
return "";
|
||||
}
|
||||
@ -260,22 +260,9 @@ static char *resolve_symref(const char *src, const char *prefix)
|
||||
|
||||
struct append_ref_cb {
|
||||
struct ref_list *ref_list;
|
||||
const char **pattern;
|
||||
int ret;
|
||||
};
|
||||
|
||||
static int match_patterns(const char **pattern, const char *refname)
|
||||
{
|
||||
if (!*pattern)
|
||||
return 1; /* no pattern always matches */
|
||||
while (*pattern) {
|
||||
if (!fnmatch(*pattern, refname, 0))
|
||||
return 1;
|
||||
pattern++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int append_ref(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
|
||||
{
|
||||
struct append_ref_cb *cb = (struct append_ref_cb *)(cb_data);
|
||||
@ -310,9 +297,6 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
|
||||
if ((kind & ref_list->kinds) == 0)
|
||||
return 0;
|
||||
|
||||
if (!match_patterns(cb->pattern, refname))
|
||||
return 0;
|
||||
|
||||
commit = NULL;
|
||||
if (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) {
|
||||
commit = lookup_commit_reference_gently(sha1, 1);
|
||||
@ -508,7 +492,7 @@ static void show_detached(struct ref_list *ref_list)
|
||||
}
|
||||
}
|
||||
|
||||
static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit, const char **pattern)
|
||||
static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit)
|
||||
{
|
||||
int i;
|
||||
struct append_ref_cb cb;
|
||||
@ -522,7 +506,6 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru
|
||||
if (merge_filter != NO_FILTER)
|
||||
init_revisions(&ref_list.revs, NULL);
|
||||
cb.ref_list = &ref_list;
|
||||
cb.pattern = pattern;
|
||||
cb.ret = 0;
|
||||
for_each_rawref(append_ref, &cb);
|
||||
if (merge_filter != NO_FILTER) {
|
||||
@ -540,7 +523,7 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru
|
||||
qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);
|
||||
|
||||
detached = (detached && (kinds & REF_LOCAL_BRANCH));
|
||||
if (detached && match_patterns(pattern, "HEAD"))
|
||||
if (detached)
|
||||
show_detached(&ref_list);
|
||||
|
||||
for (i = 0; i < ref_list.index; i++) {
|
||||
@ -583,7 +566,11 @@ static void rename_branch(const char *oldname, const char *newname, int force)
|
||||
die(_("Invalid branch name: '%s'"), oldname);
|
||||
}
|
||||
|
||||
validate_new_branchname(newname, &newref, force, 0);
|
||||
if (strbuf_check_branch_ref(&newref, newname))
|
||||
die(_("Invalid branch name: '%s'"), newname);
|
||||
|
||||
if (resolve_ref(newref.buf, sha1, 1, NULL) && !force)
|
||||
die(_("A branch named '%s' already exists."), newref.buf + 11);
|
||||
|
||||
strbuf_addf(&logmsg, "Branch: renamed %s to %s",
|
||||
oldref.buf, newref.buf);
|
||||
@ -625,8 +612,8 @@ static int opt_parse_merge_filter(const struct option *opt, const char *arg, int
|
||||
|
||||
int cmd_branch(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int delete = 0, rename = 0, force_create = 0, list = 0;
|
||||
int verbose = 0, abbrev = -1, detached = 0;
|
||||
int delete = 0, rename = 0, force_create = 0;
|
||||
int verbose = 0, abbrev = DEFAULT_ABBREV, detached = 0;
|
||||
int reflog = 0;
|
||||
enum branch_track track;
|
||||
int kinds = REF_LOCAL_BRANCH;
|
||||
@ -641,7 +628,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
|
||||
OPT_SET_INT( 0, "set-upstream", &track, "change upstream info",
|
||||
BRANCH_TRACK_OVERRIDE),
|
||||
OPT__COLOR(&branch_use_color, "use colored output"),
|
||||
OPT_SET_INT('r', "remotes", &kinds, "act on remote-tracking branches",
|
||||
OPT_SET_INT('r', NULL, &kinds, "act on remote-tracking branches",
|
||||
REF_REMOTE_BRANCH),
|
||||
{
|
||||
OPTION_CALLBACK, 0, "contains", &with_commit, "commit",
|
||||
@ -658,14 +645,13 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
|
||||
OPT__ABBREV(&abbrev),
|
||||
|
||||
OPT_GROUP("Specific git-branch actions:"),
|
||||
OPT_SET_INT('a', "all", &kinds, "list both remote-tracking and local branches",
|
||||
OPT_SET_INT('a', NULL, &kinds, "list both remote-tracking and local branches",
|
||||
REF_REMOTE_BRANCH | REF_LOCAL_BRANCH),
|
||||
OPT_BIT('d', "delete", &delete, "delete fully merged branch", 1),
|
||||
OPT_BIT('d', NULL, &delete, "delete fully merged branch", 1),
|
||||
OPT_BIT('D', NULL, &delete, "delete branch (even if not merged)", 2),
|
||||
OPT_BIT('m', "move", &rename, "move/rename a branch and its reflog", 1),
|
||||
OPT_BIT('m', NULL, &rename, "move/rename a branch and its reflog", 1),
|
||||
OPT_BIT('M', NULL, &rename, "move/rename a branch, even if target exists", 2),
|
||||
OPT_BOOLEAN(0, "list", &list, "list branch names"),
|
||||
OPT_BOOLEAN('l', "create-reflog", &reflog, "create the branch's reflog"),
|
||||
OPT_BOOLEAN('l', NULL, &reflog, "create the branch's reflog"),
|
||||
OPT__FORCE(&force_create, "force creation (when already exists)"),
|
||||
{
|
||||
OPTION_CALLBACK, 0, "no-merged", &merge_filter_ref,
|
||||
@ -687,6 +673,9 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
|
||||
|
||||
git_config(git_branch_config, NULL);
|
||||
|
||||
if (branch_use_color == -1)
|
||||
branch_use_color = git_use_color_default;
|
||||
|
||||
track = git_branch_track;
|
||||
|
||||
head = resolve_ref("HEAD", head_sha1, 0, NULL);
|
||||
@ -704,21 +693,13 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
|
||||
|
||||
argc = parse_options(argc, argv, prefix, options, builtin_branch_usage,
|
||||
0);
|
||||
|
||||
if (!delete && !rename && !force_create && argc == 0)
|
||||
list = 1;
|
||||
|
||||
if (!!delete + !!rename + !!force_create + !!list > 1)
|
||||
if (!!delete + !!rename + !!force_create > 1)
|
||||
usage_with_options(builtin_branch_usage, options);
|
||||
|
||||
if (abbrev == -1)
|
||||
abbrev = DEFAULT_ABBREV;
|
||||
|
||||
if (delete)
|
||||
return delete_branches(argc, argv, delete > 1, kinds);
|
||||
else if (list)
|
||||
return print_ref_list(kinds, detached, verbose, abbrev,
|
||||
with_commit, argv);
|
||||
else if (argc == 0)
|
||||
return print_ref_list(kinds, detached, verbose, abbrev, with_commit);
|
||||
else if (rename && (argc == 1))
|
||||
rename_branch(head, argv[0], rename > 1);
|
||||
else if (rename && (argc == 2))
|
||||
|
@ -58,7 +58,7 @@ int cmd_bundle(int argc, const char **argv, const char *prefix)
|
||||
} else if (!strcmp(cmd, "unbundle")) {
|
||||
if (!startup_info->have_repository)
|
||||
die(_("Need a repository to unbundle."));
|
||||
return !!unbundle(&header, bundle_fd, 0) ||
|
||||
return !!unbundle(&header, bundle_fd) ||
|
||||
list_bundle_refs(&header, argc, argv);
|
||||
} else
|
||||
usage(builtin_bundle_usage);
|
||||
|
@ -4,30 +4,28 @@
|
||||
#include "quote.h"
|
||||
#include "parse-options.h"
|
||||
|
||||
static int all_attrs;
|
||||
static int cached_attrs;
|
||||
static int stdin_paths;
|
||||
static const char * const check_attr_usage[] = {
|
||||
"git check-attr [-a | --all | attr...] [--] pathname...",
|
||||
"git check-attr --stdin [-a | --all | attr...] < <list-of-paths>",
|
||||
"git check-attr attr... [--] pathname...",
|
||||
"git check-attr --stdin attr... < <list-of-paths>",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int null_term_line;
|
||||
|
||||
static const struct option check_attr_options[] = {
|
||||
OPT_BOOLEAN('a', "all", &all_attrs, "report all attributes set on file"),
|
||||
OPT_BOOLEAN(0, "cached", &cached_attrs, "use .gitattributes only from the index"),
|
||||
OPT_BOOLEAN(0 , "stdin", &stdin_paths, "read file names from stdin"),
|
||||
OPT_BOOLEAN('z', NULL, &null_term_line,
|
||||
"input paths are terminated by a null character"),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
static void output_attr(int cnt, struct git_attr_check *check,
|
||||
const char *file)
|
||||
static void check_attr(int cnt, struct git_attr_check *check,
|
||||
const char** name, const char *file)
|
||||
{
|
||||
int j;
|
||||
if (git_checkattr(file, cnt, check))
|
||||
die("git_checkattr died");
|
||||
for (j = 0; j < cnt; j++) {
|
||||
const char *value = check[j].value;
|
||||
|
||||
@ -39,30 +37,12 @@ static void output_attr(int cnt, struct git_attr_check *check,
|
||||
value = "unspecified";
|
||||
|
||||
quote_c_style(file, NULL, stdout, 0);
|
||||
printf(": %s: %s\n", git_attr_name(check[j].attr), value);
|
||||
printf(": %s: %s\n", name[j], value);
|
||||
}
|
||||
}
|
||||
|
||||
static void check_attr(const char *prefix, int cnt,
|
||||
struct git_attr_check *check, const char *file)
|
||||
{
|
||||
char *full_path =
|
||||
prefix_path(prefix, prefix ? strlen(prefix) : 0, file);
|
||||
if (check != NULL) {
|
||||
if (git_check_attr(full_path, cnt, check))
|
||||
die("git_check_attr died");
|
||||
output_attr(cnt, check, file);
|
||||
} else {
|
||||
if (git_all_attrs(full_path, &cnt, &check))
|
||||
die("git_all_attrs died");
|
||||
output_attr(cnt, check, file);
|
||||
free(check);
|
||||
}
|
||||
free(full_path);
|
||||
}
|
||||
|
||||
static void check_attr_stdin_paths(const char *prefix, int cnt,
|
||||
struct git_attr_check *check)
|
||||
static void check_attr_stdin_paths(int cnt, struct git_attr_check *check,
|
||||
const char** name)
|
||||
{
|
||||
struct strbuf buf, nbuf;
|
||||
int line_termination = null_term_line ? 0 : '\n';
|
||||
@ -76,99 +56,67 @@ static void check_attr_stdin_paths(const char *prefix, int cnt,
|
||||
die("line is badly quoted");
|
||||
strbuf_swap(&buf, &nbuf);
|
||||
}
|
||||
check_attr(prefix, cnt, check, buf.buf);
|
||||
check_attr(cnt, check, name, buf.buf);
|
||||
maybe_flush_or_die(stdout, "attribute to stdout");
|
||||
}
|
||||
strbuf_release(&buf);
|
||||
strbuf_release(&nbuf);
|
||||
}
|
||||
|
||||
static NORETURN void error_with_usage(const char *msg)
|
||||
{
|
||||
error("%s", msg);
|
||||
usage_with_options(check_attr_usage, check_attr_options);
|
||||
}
|
||||
|
||||
int cmd_check_attr(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
struct git_attr_check *check;
|
||||
int cnt, i, doubledash, filei;
|
||||
|
||||
git_config(git_default_config, NULL);
|
||||
int cnt, i, doubledash;
|
||||
const char *errstr = NULL;
|
||||
|
||||
argc = parse_options(argc, argv, prefix, check_attr_options,
|
||||
check_attr_usage, PARSE_OPT_KEEP_DASHDASH);
|
||||
if (!argc)
|
||||
usage_with_options(check_attr_usage, check_attr_options);
|
||||
|
||||
if (read_cache() < 0) {
|
||||
die("invalid cache");
|
||||
}
|
||||
|
||||
if (cached_attrs)
|
||||
git_attr_set_direction(GIT_ATTR_INDEX, NULL);
|
||||
|
||||
doubledash = -1;
|
||||
for (i = 0; doubledash < 0 && i < argc; i++) {
|
||||
if (!strcmp(argv[i], "--"))
|
||||
doubledash = i;
|
||||
}
|
||||
|
||||
/* Process --all and/or attribute arguments: */
|
||||
if (all_attrs) {
|
||||
if (doubledash >= 1)
|
||||
error_with_usage("Attributes and --all both specified");
|
||||
|
||||
cnt = 0;
|
||||
filei = doubledash + 1;
|
||||
} else if (doubledash == 0) {
|
||||
error_with_usage("No attribute specified");
|
||||
} else if (doubledash < 0) {
|
||||
if (!argc)
|
||||
error_with_usage("No attribute specified");
|
||||
|
||||
if (stdin_paths) {
|
||||
/* Treat all arguments as attribute names. */
|
||||
cnt = argc;
|
||||
filei = argc;
|
||||
} else {
|
||||
/* Treat exactly one argument as an attribute name. */
|
||||
cnt = 1;
|
||||
filei = 1;
|
||||
}
|
||||
} else {
|
||||
/* If there is no double dash, we handle only one attribute */
|
||||
if (doubledash < 0) {
|
||||
cnt = 1;
|
||||
doubledash = 0;
|
||||
} else
|
||||
cnt = doubledash;
|
||||
filei = doubledash + 1;
|
||||
doubledash++;
|
||||
|
||||
if (cnt <= 0)
|
||||
errstr = "No attribute specified";
|
||||
else if (stdin_paths && doubledash < argc)
|
||||
errstr = "Can't specify files with --stdin";
|
||||
if (errstr) {
|
||||
error("%s", errstr);
|
||||
usage_with_options(check_attr_usage, check_attr_options);
|
||||
}
|
||||
|
||||
/* Check file argument(s): */
|
||||
if (stdin_paths) {
|
||||
if (filei < argc)
|
||||
error_with_usage("Can't specify files with --stdin");
|
||||
} else {
|
||||
if (filei >= argc)
|
||||
error_with_usage("No file specified");
|
||||
}
|
||||
|
||||
if (all_attrs) {
|
||||
check = NULL;
|
||||
} else {
|
||||
check = xcalloc(cnt, sizeof(*check));
|
||||
for (i = 0; i < cnt; i++) {
|
||||
const char *name;
|
||||
struct git_attr *a;
|
||||
name = argv[i];
|
||||
a = git_attr(name);
|
||||
if (!a)
|
||||
return error("%s: not a valid attribute name",
|
||||
name);
|
||||
check[i].attr = a;
|
||||
}
|
||||
check = xcalloc(cnt, sizeof(*check));
|
||||
for (i = 0; i < cnt; i++) {
|
||||
const char *name;
|
||||
struct git_attr *a;
|
||||
name = argv[i];
|
||||
a = git_attr(name);
|
||||
if (!a)
|
||||
return error("%s: not a valid attribute name", name);
|
||||
check[i].attr = a;
|
||||
}
|
||||
|
||||
if (stdin_paths)
|
||||
check_attr_stdin_paths(prefix, cnt, check);
|
||||
check_attr_stdin_paths(cnt, check, argv);
|
||||
else {
|
||||
for (i = filei; i < argc; i++)
|
||||
check_attr(prefix, cnt, check, argv[i]);
|
||||
for (i = doubledash; i < argc; i++)
|
||||
check_attr(cnt, check, argv, argv[i]);
|
||||
maybe_flush_or_die(stdout, "attribute to stdout");
|
||||
}
|
||||
return 0;
|
||||
|
@ -8,32 +8,29 @@
|
||||
#include "strbuf.h"
|
||||
|
||||
static const char builtin_check_ref_format_usage[] =
|
||||
"git check-ref-format [--normalize] [options] <refname>\n"
|
||||
"git check-ref-format [--print] <refname>\n"
|
||||
" or: git check-ref-format --branch <branchname-shorthand>";
|
||||
|
||||
/*
|
||||
* Return a copy of refname but with leading slashes removed and runs
|
||||
* of adjacent slashes replaced with single slashes.
|
||||
* Remove leading slashes and replace each run of adjacent slashes in
|
||||
* src with a single slash, and write the result to dst.
|
||||
*
|
||||
* This function is similar to normalize_path_copy(), but stripped down
|
||||
* to meet check_ref_format's simpler needs.
|
||||
*/
|
||||
static char *collapse_slashes(const char *refname)
|
||||
static void collapse_slashes(char *dst, const char *src)
|
||||
{
|
||||
char *ret = xmalloc(strlen(refname) + 1);
|
||||
char ch;
|
||||
char prev = '/';
|
||||
char *cp = ret;
|
||||
|
||||
while ((ch = *refname++) != '\0') {
|
||||
while ((ch = *src++) != '\0') {
|
||||
if (prev == '/' && ch == prev)
|
||||
continue;
|
||||
|
||||
*cp++ = ch;
|
||||
*dst++ = ch;
|
||||
prev = ch;
|
||||
}
|
||||
*cp = '\0';
|
||||
return ret;
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
static int check_ref_format_branch(const char *arg)
|
||||
@ -48,41 +45,27 @@ static int check_ref_format_branch(const char *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_ref_format_print(const char *arg)
|
||||
{
|
||||
char *refname = xmalloc(strlen(arg) + 1);
|
||||
|
||||
if (check_ref_format(arg))
|
||||
return 1;
|
||||
collapse_slashes(refname, arg);
|
||||
printf("%s\n", refname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int i;
|
||||
int normalize = 0;
|
||||
int flags = 0;
|
||||
const char *refname;
|
||||
|
||||
if (argc == 2 && !strcmp(argv[1], "-h"))
|
||||
usage(builtin_check_ref_format_usage);
|
||||
|
||||
if (argc == 3 && !strcmp(argv[1], "--branch"))
|
||||
return check_ref_format_branch(argv[2]);
|
||||
|
||||
for (i = 1; i < argc && argv[i][0] == '-'; i++) {
|
||||
if (!strcmp(argv[i], "--normalize") || !strcmp(argv[i], "--print"))
|
||||
normalize = 1;
|
||||
else if (!strcmp(argv[i], "--allow-onelevel"))
|
||||
flags |= REFNAME_ALLOW_ONELEVEL;
|
||||
else if (!strcmp(argv[i], "--no-allow-onelevel"))
|
||||
flags &= ~REFNAME_ALLOW_ONELEVEL;
|
||||
else if (!strcmp(argv[i], "--refspec-pattern"))
|
||||
flags |= REFNAME_REFSPEC_PATTERN;
|
||||
else
|
||||
usage(builtin_check_ref_format_usage);
|
||||
}
|
||||
if (! (i == argc - 1))
|
||||
if (argc == 3 && !strcmp(argv[1], "--print"))
|
||||
return check_ref_format_print(argv[2]);
|
||||
if (argc != 2)
|
||||
usage(builtin_check_ref_format_usage);
|
||||
|
||||
refname = argv[i];
|
||||
if (normalize)
|
||||
refname = collapse_slashes(refname);
|
||||
if (check_refname_format(refname, flags))
|
||||
return 1;
|
||||
if (normalize)
|
||||
printf("%s\n", refname);
|
||||
|
||||
return 0;
|
||||
return !!check_ref_format(argv[1]);
|
||||
}
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "ll-merge.h"
|
||||
#include "resolve-undo.h"
|
||||
#include "submodule.h"
|
||||
#include "argv-array.h"
|
||||
|
||||
static const char * const checkout_usage[] = {
|
||||
"git checkout [options] <branch>",
|
||||
@ -72,7 +71,7 @@ static int update_some(const unsigned char *sha1, const char *base, int baselen,
|
||||
hashcpy(ce->sha1, sha1);
|
||||
memcpy(ce->name, base, baselen);
|
||||
memcpy(ce->name + baselen, pathname, len - baselen);
|
||||
ce->ce_flags = create_ce_flags(len, 0) | CE_UPDATE;
|
||||
ce->ce_flags = create_ce_flags(len, 0);
|
||||
ce->ce_mode = create_ce_mode(mode);
|
||||
add_cache_entry(ce, ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE);
|
||||
return 0;
|
||||
@ -229,8 +228,6 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec,
|
||||
|
||||
for (pos = 0; pos < active_nr; pos++) {
|
||||
struct cache_entry *ce = active_cache[pos];
|
||||
if (source_tree && !(ce->ce_flags & CE_UPDATE))
|
||||
continue;
|
||||
match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, ps_matched);
|
||||
}
|
||||
|
||||
@ -269,8 +266,6 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec,
|
||||
state.refresh_cache = 1;
|
||||
for (pos = 0; pos < active_nr; pos++) {
|
||||
struct cache_entry *ce = active_cache[pos];
|
||||
if (source_tree && !(ce->ce_flags & CE_UPDATE))
|
||||
continue;
|
||||
if (match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, NULL)) {
|
||||
if (!ce_stage(ce)) {
|
||||
errs |= checkout_entry(ce, &state, NULL);
|
||||
@ -593,11 +588,35 @@ static void update_refs_for_switch(struct checkout_opts *opts,
|
||||
report_tracking(new);
|
||||
}
|
||||
|
||||
static int add_pending_uninteresting_ref(const char *refname,
|
||||
const unsigned char *sha1,
|
||||
int flags, void *cb_data)
|
||||
struct rev_list_args {
|
||||
int argc;
|
||||
int alloc;
|
||||
const char **argv;
|
||||
};
|
||||
|
||||
static void add_one_rev_list_arg(struct rev_list_args *args, const char *s)
|
||||
{
|
||||
add_pending_sha1(cb_data, refname, sha1, flags | UNINTERESTING);
|
||||
ALLOC_GROW(args->argv, args->argc + 1, args->alloc);
|
||||
args->argv[args->argc++] = s;
|
||||
}
|
||||
|
||||
static int add_one_ref_to_rev_list_arg(const char *refname,
|
||||
const unsigned char *sha1,
|
||||
int flags,
|
||||
void *cb_data)
|
||||
{
|
||||
add_one_rev_list_arg(cb_data, refname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clear_commit_marks_from_one_ref(const char *refname,
|
||||
const unsigned char *sha1,
|
||||
int flags,
|
||||
void *cb_data)
|
||||
{
|
||||
struct commit *commit = lookup_commit_reference_gently(sha1, 1);
|
||||
if (commit)
|
||||
clear_commit_marks(commit, -1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -638,25 +657,24 @@ 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",
|
||||
"%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",
|
||||
/* The plural version */
|
||||
"Warning: you are leaving %d commits behind, "
|
||||
"not connected to\n"
|
||||
"any of your branches:\n\n"
|
||||
"%s\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",
|
||||
/* Give ngettext() the count */
|
||||
lost),
|
||||
lost,
|
||||
sb.buf);
|
||||
sb.buf,
|
||||
sha1_to_hex(commit->object.sha1));
|
||||
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));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -666,21 +684,19 @@ static void suggest_reattach(struct commit *commit, struct rev_info *revs)
|
||||
*/
|
||||
static void orphaned_commit_warning(struct commit *commit)
|
||||
{
|
||||
struct rev_list_args args = { 0, 0, NULL };
|
||||
struct rev_info revs;
|
||||
struct object *object = &commit->object;
|
||||
struct object_array refs;
|
||||
|
||||
add_one_rev_list_arg(&args, "(internal)");
|
||||
add_one_rev_list_arg(&args, sha1_to_hex(commit->object.sha1));
|
||||
add_one_rev_list_arg(&args, "--not");
|
||||
for_each_ref(add_one_ref_to_rev_list_arg, &args);
|
||||
add_one_rev_list_arg(&args, "--");
|
||||
add_one_rev_list_arg(&args, NULL);
|
||||
|
||||
init_revisions(&revs, NULL);
|
||||
setup_revisions(0, NULL, &revs, NULL);
|
||||
|
||||
object->flags &= ~UNINTERESTING;
|
||||
add_pending_object(&revs, object, sha1_to_hex(object->sha1));
|
||||
|
||||
for_each_ref(add_pending_uninteresting_ref, &revs);
|
||||
|
||||
refs = revs.pending;
|
||||
revs.leak_pending = 1;
|
||||
|
||||
if (setup_revisions(args.argc - 1, args.argv, &revs, NULL) != 1)
|
||||
die(_("internal error: only -- alone should have been left"));
|
||||
if (prepare_revision_walk(&revs))
|
||||
die(_("internal error in revision walk"));
|
||||
if (!(commit->object.flags & UNINTERESTING))
|
||||
@ -688,8 +704,8 @@ static void orphaned_commit_warning(struct commit *commit)
|
||||
else
|
||||
describe_detached_head(_("Previous HEAD position was"), commit);
|
||||
|
||||
clear_commit_marks_for_object_array(&refs, ALL_REV_FLAGS);
|
||||
free(refs.objects);
|
||||
clear_commit_marks(commit, -1);
|
||||
for_each_ref(clear_commit_marks_from_one_ref, NULL);
|
||||
}
|
||||
|
||||
static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
|
||||
@ -865,7 +881,7 @@ static int parse_branchname_arg(int argc, const char **argv,
|
||||
new->name = arg;
|
||||
setup_branch_path(new);
|
||||
|
||||
if (!check_refname_format(new->path, 0) &&
|
||||
if (check_ref_format(new->path) == CHECK_REF_FORMAT_OK &&
|
||||
resolve_ref(new->path, branch_rev, 1, NULL))
|
||||
hashcpy(rev, branch_rev);
|
||||
else
|
||||
@ -1055,10 +1071,15 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
|
||||
|
||||
if (opts.new_branch) {
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
|
||||
opts.branch_exists = validate_new_branchname(opts.new_branch, &buf,
|
||||
!!opts.new_branch_force, 0);
|
||||
|
||||
if (strbuf_check_branch_ref(&buf, opts.new_branch))
|
||||
die(_("git checkout: we do not like '%s' as a branch name."),
|
||||
opts.new_branch);
|
||||
if (ref_exists(buf.buf)) {
|
||||
opts.branch_exists = 1;
|
||||
if (!opts.new_branch_force)
|
||||
die(_("git checkout: branch %s already exists"),
|
||||
opts.new_branch);
|
||||
}
|
||||
strbuf_release(&buf);
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
|
||||
OPT_BOOLEAN('d', NULL, &remove_directories,
|
||||
"remove whole directories"),
|
||||
{ OPTION_CALLBACK, 'e', "exclude", &exclude_list, "pattern",
|
||||
"add <pattern> to ignore rules", PARSE_OPT_NONEG, exclude_cb },
|
||||
"exclude <pattern>", PARSE_OPT_NONEG, exclude_cb },
|
||||
OPT_BOOLEAN('x', NULL, &ignored, "remove ignored files, too"),
|
||||
OPT_BOOLEAN('X', NULL, &ignored_only,
|
||||
"remove only ignored files"),
|
||||
@ -98,8 +98,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
|
||||
setup_standard_excludes(&dir);
|
||||
|
||||
for (i = 0; i < exclude_list.nr; i++)
|
||||
add_exclude(exclude_list.items[i].string, "", 0,
|
||||
&dir.exclude_list[EXC_CMDL]);
|
||||
add_exclude(exclude_list.items[i].string, "", 0, dir.exclude_list);
|
||||
|
||||
pathspec = get_pathspec(prefix, argv);
|
||||
|
||||
|
@ -46,7 +46,6 @@ static const char *real_git_dir;
|
||||
static char *option_upload_pack = "git-upload-pack";
|
||||
static int option_verbosity;
|
||||
static int option_progress;
|
||||
static struct string_list option_config;
|
||||
static struct string_list option_reference;
|
||||
|
||||
static int opt_parse_reference(const struct option *opt, const char *arg, int unset)
|
||||
@ -94,8 +93,7 @@ static struct option builtin_clone_options[] = {
|
||||
"create a shallow clone of that depth"),
|
||||
OPT_STRING(0, "separate-git-dir", &real_git_dir, "gitdir",
|
||||
"separate git dir from working tree"),
|
||||
OPT_STRING_LIST('c', "config", &option_config, "key=value",
|
||||
"set config inside the new repository"),
|
||||
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
@ -423,9 +421,8 @@ static void remove_junk_on_signal(int signo)
|
||||
static struct ref *wanted_peer_refs(const struct ref *refs,
|
||||
struct refspec *refspec)
|
||||
{
|
||||
struct ref *head = copy_ref(find_ref_by_name(refs, "HEAD"));
|
||||
struct ref *local_refs = head;
|
||||
struct ref **tail = head ? &head->next : &local_refs;
|
||||
struct ref *local_refs = NULL;
|
||||
struct ref **tail = &local_refs;
|
||||
|
||||
get_fetch_map(refs, refspec, &tail, 0);
|
||||
if (!option_mirror)
|
||||
@ -438,32 +435,13 @@ static void write_remote_refs(const struct ref *local_refs)
|
||||
{
|
||||
const struct ref *r;
|
||||
|
||||
for (r = local_refs; r; r = r->next) {
|
||||
if (!r->peer_ref)
|
||||
continue;
|
||||
for (r = local_refs; r; r = r->next)
|
||||
add_extra_ref(r->peer_ref->name, r->old_sha1, 0);
|
||||
}
|
||||
|
||||
pack_refs(PACK_REFS_ALL);
|
||||
clear_extra_refs();
|
||||
}
|
||||
|
||||
static int write_one_config(const char *key, const char *value, void *data)
|
||||
{
|
||||
return git_config_set_multivar(key, value ? value : "true", "^$", 0);
|
||||
}
|
||||
|
||||
static void write_config(struct string_list *config)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < config->nr; i++) {
|
||||
if (git_config_parse_parameter(config->items[i].string,
|
||||
write_one_config, NULL) < 0)
|
||||
die("unable to write parameters to config file");
|
||||
}
|
||||
}
|
||||
|
||||
int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int is_bundle = 0, is_local;
|
||||
@ -577,12 +555,11 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
|
||||
if (0 <= option_verbosity) {
|
||||
if (option_bare)
|
||||
printf(_("Cloning into bare repository '%s'...\n"), dir);
|
||||
printf(_("Cloning into bare repository %s...\n"), dir);
|
||||
else
|
||||
printf(_("Cloning into '%s'...\n"), dir);
|
||||
printf(_("Cloning into %s...\n"), dir);
|
||||
}
|
||||
init_db(option_template, INIT_DB_QUIET);
|
||||
write_config(&option_config);
|
||||
|
||||
/*
|
||||
* At this point, the config exists, so we do not need the
|
||||
|
111
builtin/commit.c
111
builtin/commit.c
@ -62,6 +62,8 @@ N_("The previous cherry-pick is now empty, possibly due to conflict resolution.\
|
||||
"\n"
|
||||
"Otherwise, please use 'git reset'\n");
|
||||
|
||||
static unsigned char head_sha1[20];
|
||||
|
||||
static const char *use_message_buffer;
|
||||
static const char commit_editmsg[] = "COMMIT_EDITMSG";
|
||||
static struct lock_file index_lock; /* real index */
|
||||
@ -100,7 +102,7 @@ static enum {
|
||||
static char *cleanup_arg;
|
||||
|
||||
static enum commit_whence whence;
|
||||
static int use_editor = 1, include_status = 1;
|
||||
static int use_editor = 1, initial_commit, include_status = 1;
|
||||
static int show_ignored_in_status;
|
||||
static const char *only_include_assumed;
|
||||
static struct strbuf message;
|
||||
@ -254,11 +256,8 @@ static int list_paths(struct string_list *list, const char *with_tree,
|
||||
;
|
||||
m = xcalloc(1, i);
|
||||
|
||||
if (with_tree) {
|
||||
char *max_prefix = common_prefix(pattern);
|
||||
overlay_tree_on_cache(with_tree, max_prefix ? max_prefix : prefix);
|
||||
free(max_prefix);
|
||||
}
|
||||
if (with_tree)
|
||||
overlay_tree_on_cache(with_tree, prefix);
|
||||
|
||||
for (i = 0; i < active_nr; i++) {
|
||||
struct cache_entry *ce = active_cache[i];
|
||||
@ -295,13 +294,13 @@ static void add_remove_files(struct string_list *list)
|
||||
}
|
||||
}
|
||||
|
||||
static void create_base_index(const struct commit *current_head)
|
||||
static void create_base_index(void)
|
||||
{
|
||||
struct tree *tree;
|
||||
struct unpack_trees_options opts;
|
||||
struct tree_desc t;
|
||||
|
||||
if (!current_head) {
|
||||
if (initial_commit) {
|
||||
discard_cache();
|
||||
return;
|
||||
}
|
||||
@ -314,7 +313,7 @@ static void create_base_index(const struct commit *current_head)
|
||||
opts.dst_index = &the_index;
|
||||
|
||||
opts.fn = oneway_merge;
|
||||
tree = parse_tree_indirect(current_head->object.sha1);
|
||||
tree = parse_tree_indirect(head_sha1);
|
||||
if (!tree)
|
||||
die(_("failed to unpack HEAD tree object"));
|
||||
parse_tree(tree);
|
||||
@ -333,8 +332,7 @@ static void refresh_cache_or_die(int refresh_flags)
|
||||
die_resolve_conflict("commit");
|
||||
}
|
||||
|
||||
static char *prepare_index(int argc, const char **argv, const char *prefix,
|
||||
const struct commit *current_head, int is_status)
|
||||
static char *prepare_index(int argc, const char **argv, const char *prefix, int is_status)
|
||||
{
|
||||
int fd;
|
||||
struct string_list partial;
|
||||
@ -450,7 +448,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
|
||||
|
||||
memset(&partial, 0, sizeof(partial));
|
||||
partial.strdup_strings = 1;
|
||||
if (list_paths(&partial, !current_head ? NULL : "HEAD", prefix, pathspec))
|
||||
if (list_paths(&partial, initial_commit ? NULL : "HEAD", prefix, pathspec))
|
||||
exit(1);
|
||||
|
||||
discard_cache();
|
||||
@ -469,7 +467,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
|
||||
(uintmax_t) getpid()),
|
||||
LOCK_DIE_ON_ERROR);
|
||||
|
||||
create_base_index(current_head);
|
||||
create_base_index();
|
||||
add_remove_files(&partial);
|
||||
refresh_cache(REFRESH_QUIET);
|
||||
|
||||
@ -518,9 +516,12 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int
|
||||
return s->commitable;
|
||||
}
|
||||
|
||||
static int is_a_merge(const struct commit *current_head)
|
||||
static int is_a_merge(const unsigned char *sha1)
|
||||
{
|
||||
return !!(current_head->parents && current_head->parents->next);
|
||||
struct commit *commit = lookup_commit(sha1);
|
||||
if (!commit || parse_commit(commit))
|
||||
die(_("could not parse HEAD commit"));
|
||||
return !!(commit->parents && commit->parents->next);
|
||||
}
|
||||
|
||||
static const char sign_off_header[] = "Signed-off-by: ";
|
||||
@ -624,7 +625,6 @@ static char *cut_ident_timestamp_part(char *string)
|
||||
}
|
||||
|
||||
static int prepare_to_commit(const char *index_file, const char *prefix,
|
||||
struct commit *current_head,
|
||||
struct wt_status *s,
|
||||
struct strbuf *author_ident)
|
||||
{
|
||||
@ -846,7 +846,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
|
||||
* empty due to conflict resolution, which the user should okay.
|
||||
*/
|
||||
if (!commitable && whence != FROM_MERGE && !allow_empty &&
|
||||
!(amend && is_a_merge(current_head))) {
|
||||
!(amend && is_a_merge(head_sha1))) {
|
||||
run_status(stdout, index_file, prefix, 0, s);
|
||||
if (amend)
|
||||
fputs(_(empty_amend_advice), stderr);
|
||||
@ -1004,7 +1004,6 @@ static const char *read_commit_message(const char *name)
|
||||
static int parse_and_validate_options(int argc, const char *argv[],
|
||||
const char * const usage[],
|
||||
const char *prefix,
|
||||
struct commit *current_head,
|
||||
struct wt_status *s)
|
||||
{
|
||||
int f = 0;
|
||||
@ -1025,8 +1024,11 @@ static int parse_and_validate_options(int argc, const char *argv[],
|
||||
if (!use_editor)
|
||||
setenv("GIT_EDITOR", ":", 1);
|
||||
|
||||
if (get_sha1("HEAD", head_sha1))
|
||||
initial_commit = 1;
|
||||
|
||||
/* Sanity check options */
|
||||
if (amend && !current_head)
|
||||
if (amend && initial_commit)
|
||||
die(_("You have nothing to amend."));
|
||||
if (amend && whence != FROM_COMMIT)
|
||||
die(_("You are in the middle of a %s -- cannot amend."), whence_s());
|
||||
@ -1098,12 +1100,12 @@ static int parse_and_validate_options(int argc, const char *argv[],
|
||||
}
|
||||
|
||||
static int dry_run_commit(int argc, const char **argv, const char *prefix,
|
||||
const struct commit *current_head, struct wt_status *s)
|
||||
struct wt_status *s)
|
||||
{
|
||||
int commitable;
|
||||
const char *index_file;
|
||||
|
||||
index_file = prepare_index(argc, argv, prefix, current_head, 1);
|
||||
index_file = prepare_index(argc, argv, prefix, 1);
|
||||
commitable = run_status(stdout, index_file, prefix, 0, s);
|
||||
rollback_index_files();
|
||||
|
||||
@ -1142,7 +1144,7 @@ static int git_status_config(const char *k, const char *v, void *cb)
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(k, "status.color") || !strcmp(k, "color.status")) {
|
||||
s->use_color = git_config_colorbool(k, v);
|
||||
s->use_color = git_config_colorbool(k, v, -1);
|
||||
return 0;
|
||||
}
|
||||
if (!prefixcmp(k, "status.color.") || !prefixcmp(k, "color.status.")) {
|
||||
@ -1235,6 +1237,10 @@ int cmd_status(int argc, const char **argv, const char *prefix)
|
||||
|
||||
if (s.relative_paths)
|
||||
s.prefix = prefix;
|
||||
if (s.use_color == -1)
|
||||
s.use_color = git_use_color_default;
|
||||
if (diff_use_color_default == -1)
|
||||
diff_use_color_default = git_use_color_default;
|
||||
|
||||
switch (status_format) {
|
||||
case STATUS_FORMAT_SHORT:
|
||||
@ -1252,8 +1258,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_summary(const char *prefix, const unsigned char *sha1,
|
||||
int initial_commit)
|
||||
static void print_summary(const char *prefix, const unsigned char *sha1)
|
||||
{
|
||||
struct rev_info rev;
|
||||
struct commit *commit;
|
||||
@ -1375,13 +1380,12 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
||||
struct strbuf author_ident = STRBUF_INIT;
|
||||
const char *index_file, *reflog_msg;
|
||||
char *nl, *p;
|
||||
unsigned char sha1[20];
|
||||
unsigned char commit_sha1[20];
|
||||
struct ref_lock *ref_lock;
|
||||
struct commit_list *parents = NULL, **pptr = &parents;
|
||||
struct stat statbuf;
|
||||
int allow_fast_forward = 1;
|
||||
struct wt_status s;
|
||||
struct commit *current_head = NULL;
|
||||
|
||||
if (argc == 2 && !strcmp(argv[1], "-h"))
|
||||
usage_with_options(builtin_commit_usage, builtin_commit_options);
|
||||
@ -1390,47 +1394,48 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
||||
git_config(git_commit_config, &s);
|
||||
determine_whence(&s);
|
||||
|
||||
if (get_sha1("HEAD", sha1))
|
||||
current_head = NULL;
|
||||
else {
|
||||
current_head = lookup_commit_or_die(sha1, "HEAD");
|
||||
if (!current_head || parse_commit(current_head))
|
||||
die(_("could not parse HEAD commit"));
|
||||
}
|
||||
if (s.use_color == -1)
|
||||
s.use_color = git_use_color_default;
|
||||
argc = parse_and_validate_options(argc, argv, builtin_commit_usage,
|
||||
prefix, current_head, &s);
|
||||
if (dry_run)
|
||||
return dry_run_commit(argc, argv, prefix, current_head, &s);
|
||||
index_file = prepare_index(argc, argv, prefix, current_head, 0);
|
||||
prefix, &s);
|
||||
if (dry_run) {
|
||||
if (diff_use_color_default == -1)
|
||||
diff_use_color_default = git_use_color_default;
|
||||
return dry_run_commit(argc, argv, prefix, &s);
|
||||
}
|
||||
index_file = prepare_index(argc, argv, prefix, 0);
|
||||
|
||||
/* Set up everything for writing the commit object. This includes
|
||||
running hooks, writing the trees, and interacting with the user. */
|
||||
if (!prepare_to_commit(index_file, prefix,
|
||||
current_head, &s, &author_ident)) {
|
||||
if (!prepare_to_commit(index_file, prefix, &s, &author_ident)) {
|
||||
rollback_index_files();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Determine parents */
|
||||
reflog_msg = getenv("GIT_REFLOG_ACTION");
|
||||
if (!current_head) {
|
||||
if (initial_commit) {
|
||||
if (!reflog_msg)
|
||||
reflog_msg = "commit (initial)";
|
||||
} else if (amend) {
|
||||
struct commit_list *c;
|
||||
struct commit *commit;
|
||||
|
||||
if (!reflog_msg)
|
||||
reflog_msg = "commit (amend)";
|
||||
for (c = current_head->parents; c; c = c->next)
|
||||
commit = lookup_commit(head_sha1);
|
||||
if (!commit || parse_commit(commit))
|
||||
die(_("could not parse HEAD commit"));
|
||||
|
||||
for (c = commit->parents; c; c = c->next)
|
||||
pptr = &commit_list_insert(c->item, pptr)->next;
|
||||
} else if (whence == FROM_MERGE) {
|
||||
struct strbuf m = STRBUF_INIT;
|
||||
struct commit *commit;
|
||||
FILE *fp;
|
||||
|
||||
if (!reflog_msg)
|
||||
reflog_msg = "commit (merge)";
|
||||
pptr = &commit_list_insert(current_head, pptr)->next;
|
||||
pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
|
||||
fp = fopen(git_path("MERGE_HEAD"), "r");
|
||||
if (fp == NULL)
|
||||
die_errno(_("could not open '%s' for reading"),
|
||||
@ -1439,8 +1444,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
||||
unsigned char sha1[20];
|
||||
if (get_sha1_hex(m.buf, sha1) < 0)
|
||||
die(_("Corrupt MERGE_HEAD file (%s)"), m.buf);
|
||||
commit = lookup_commit_or_die(sha1, "MERGE_HEAD");
|
||||
pptr = &commit_list_insert(commit, pptr)->next;
|
||||
pptr = &commit_list_insert(lookup_commit(sha1), pptr)->next;
|
||||
}
|
||||
fclose(fp);
|
||||
strbuf_release(&m);
|
||||
@ -1457,7 +1461,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
||||
reflog_msg = (whence == FROM_CHERRY_PICK)
|
||||
? "commit (cherry-pick)"
|
||||
: "commit";
|
||||
pptr = &commit_list_insert(current_head, pptr)->next;
|
||||
pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
|
||||
}
|
||||
|
||||
/* Finally, get the commit message */
|
||||
@ -1483,7 +1487,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (commit_tree(sb.buf, active_cache_tree->sha1, parents, sha1,
|
||||
if (commit_tree(sb.buf, active_cache_tree->sha1, parents, commit_sha1,
|
||||
author_ident.buf)) {
|
||||
rollback_index_files();
|
||||
die(_("failed to write commit object"));
|
||||
@ -1491,9 +1495,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
||||
strbuf_release(&author_ident);
|
||||
|
||||
ref_lock = lock_any_ref_for_update("HEAD",
|
||||
!current_head
|
||||
? NULL
|
||||
: current_head->object.sha1,
|
||||
initial_commit ? NULL : head_sha1,
|
||||
0);
|
||||
|
||||
nl = strchr(sb.buf, '\n');
|
||||
@ -1508,7 +1510,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
||||
rollback_index_files();
|
||||
die(_("cannot lock HEAD ref"));
|
||||
}
|
||||
if (write_ref_sha1(ref_lock, sha1, sb.buf) < 0) {
|
||||
if (write_ref_sha1(ref_lock, commit_sha1, sb.buf) < 0) {
|
||||
rollback_index_files();
|
||||
die(_("cannot update HEAD ref"));
|
||||
}
|
||||
@ -1530,14 +1532,13 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
||||
struct notes_rewrite_cfg *cfg;
|
||||
cfg = init_copy_notes_for_rewrite("amend");
|
||||
if (cfg) {
|
||||
/* we are amending, so current_head is not NULL */
|
||||
copy_note_for_rewrite(cfg, current_head->object.sha1, sha1);
|
||||
copy_note_for_rewrite(cfg, head_sha1, commit_sha1);
|
||||
finish_copy_notes_for_rewrite(cfg);
|
||||
}
|
||||
run_rewrite_hook(current_head->object.sha1, sha1);
|
||||
run_rewrite_hook(head_sha1, commit_sha1);
|
||||
}
|
||||
if (!quiet)
|
||||
print_summary(prefix, sha1, !current_head);
|
||||
print_summary(prefix, commit_sha1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -99,7 +99,6 @@ static int show_config(const char *key_, const char *value_, void *cb)
|
||||
const char *vptr = value;
|
||||
int must_free_vptr = 0;
|
||||
int dup_error = 0;
|
||||
int must_print_delim = 0;
|
||||
|
||||
if (!use_key_regexp && strcmp(key_, key))
|
||||
return 0;
|
||||
@ -110,8 +109,10 @@ static int show_config(const char *key_, const char *value_, void *cb)
|
||||
return 0;
|
||||
|
||||
if (show_keys) {
|
||||
printf("%s", key_);
|
||||
must_print_delim = 1;
|
||||
if (value_)
|
||||
printf("%s%c", key_, key_delim);
|
||||
else
|
||||
printf("%s", key_);
|
||||
}
|
||||
if (seen && !do_all)
|
||||
dup_error = 1;
|
||||
@ -129,23 +130,16 @@ static int show_config(const char *key_, const char *value_, void *cb)
|
||||
} else if (types == TYPE_PATH) {
|
||||
git_config_pathname(&vptr, key_, value_);
|
||||
must_free_vptr = 1;
|
||||
} else if (value_) {
|
||||
vptr = value_;
|
||||
} else {
|
||||
/* Just show the key name */
|
||||
vptr = "";
|
||||
must_print_delim = 0;
|
||||
}
|
||||
else
|
||||
vptr = value_?value_:"";
|
||||
seen++;
|
||||
if (dup_error) {
|
||||
error("More than one value for the key %s: %s",
|
||||
key_, vptr);
|
||||
}
|
||||
else {
|
||||
if (must_print_delim)
|
||||
printf("%c", key_delim);
|
||||
else
|
||||
printf("%s%c", vptr, term);
|
||||
}
|
||||
if (must_free_vptr)
|
||||
/* If vptr must be freed, it's a pointer to a
|
||||
* dynamically allocated buffer, it's safe to cast to
|
||||
@ -309,18 +303,24 @@ static void get_color(const char *def_color)
|
||||
fputs(parsed_color, stdout);
|
||||
}
|
||||
|
||||
static int stdout_is_tty;
|
||||
static int get_colorbool_found;
|
||||
static int get_diff_color_found;
|
||||
static int get_color_ui_found;
|
||||
static int git_get_colorbool_config(const char *var, const char *value,
|
||||
void *cb)
|
||||
{
|
||||
if (!strcmp(var, get_colorbool_slot))
|
||||
get_colorbool_found = git_config_colorbool(var, value);
|
||||
else if (!strcmp(var, "diff.color"))
|
||||
get_diff_color_found = git_config_colorbool(var, value);
|
||||
else if (!strcmp(var, "color.ui"))
|
||||
get_color_ui_found = git_config_colorbool(var, value);
|
||||
if (!strcmp(var, get_colorbool_slot)) {
|
||||
get_colorbool_found =
|
||||
git_config_colorbool(var, value, stdout_is_tty);
|
||||
}
|
||||
if (!strcmp(var, "diff.color")) {
|
||||
get_diff_color_found =
|
||||
git_config_colorbool(var, value, stdout_is_tty);
|
||||
}
|
||||
if (!strcmp(var, "color.ui")) {
|
||||
git_use_color_default = git_config_colorbool(var, value, stdout_is_tty);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -334,11 +334,9 @@ static int get_colorbool(int print)
|
||||
if (!strcmp(get_colorbool_slot, "color.diff"))
|
||||
get_colorbool_found = get_diff_color_found;
|
||||
if (get_colorbool_found < 0)
|
||||
get_colorbool_found = get_color_ui_found;
|
||||
get_colorbool_found = git_use_color_default;
|
||||
}
|
||||
|
||||
get_colorbool_found = want_color(get_colorbool_found);
|
||||
|
||||
if (print) {
|
||||
printf("%s\n", get_colorbool_found ? "true" : "false");
|
||||
return 0;
|
||||
@ -512,7 +510,9 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
else if (actions == ACTION_GET_COLORBOOL) {
|
||||
if (argc == 1)
|
||||
color_stdout_is_tty = git_config_bool("command line", argv[0]);
|
||||
stdout_is_tty = git_config_bool("command line", argv[0]);
|
||||
else if (argc == 0)
|
||||
stdout_is_tty = isatty(1);
|
||||
return get_colorbool(argc != 0);
|
||||
}
|
||||
|
||||
|
@ -277,6 +277,9 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
|
||||
gitmodules_config();
|
||||
git_config(git_diff_ui_config, NULL);
|
||||
|
||||
if (diff_use_color_default == -1)
|
||||
diff_use_color_default = git_use_color_default;
|
||||
|
||||
init_revisions(&rev, prefix);
|
||||
|
||||
/* If this is a no-index diff, just run it and exit there. */
|
||||
|
@ -27,7 +27,6 @@ static int progress;
|
||||
static enum { ABORT, VERBATIM, WARN, STRIP } signed_tag_mode = ABORT;
|
||||
static enum { ERROR, DROP, REWRITE } tag_of_filtered_mode = ABORT;
|
||||
static int fake_missing_tagger;
|
||||
static int use_done_feature;
|
||||
static int no_data;
|
||||
static int full_tree;
|
||||
|
||||
@ -645,8 +644,6 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
|
||||
"Fake a tagger when tags lack one"),
|
||||
OPT_BOOLEAN(0, "full-tree", &full_tree,
|
||||
"Output full tree for each commit"),
|
||||
OPT_BOOLEAN(0, "use-done-feature", &use_done_feature,
|
||||
"Use the done feature to terminate the stream"),
|
||||
{ OPTION_NEGBIT, 0, "data", &no_data, NULL,
|
||||
"Skip output of blob data",
|
||||
PARSE_OPT_NOARG | PARSE_OPT_NEGHELP, NULL, 1 },
|
||||
@ -668,9 +665,6 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
|
||||
if (argc > 1)
|
||||
usage_with_options (fast_export_usage, options);
|
||||
|
||||
if (use_done_feature)
|
||||
printf("feature done\n");
|
||||
|
||||
if (import_filename)
|
||||
import_marks(import_filename);
|
||||
|
||||
@ -698,8 +692,5 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
|
||||
if (export_filename)
|
||||
export_marks(export_filename);
|
||||
|
||||
if (use_done_feature)
|
||||
printf("done\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -15,9 +15,7 @@ static int transfer_unpack_limit = -1;
|
||||
static int fetch_unpack_limit = -1;
|
||||
static int unpack_limit = 100;
|
||||
static int prefer_ofs_delta = 1;
|
||||
static int no_done;
|
||||
static int fetch_fsck_objects = -1;
|
||||
static int transfer_fsck_objects = -1;
|
||||
static int no_done = 0;
|
||||
static struct fetch_pack_args args = {
|
||||
/* .uploadpack = */ "git-upload-pack",
|
||||
};
|
||||
@ -187,36 +185,6 @@ static void consume_shallow_list(int fd)
|
||||
}
|
||||
}
|
||||
|
||||
struct write_shallow_data {
|
||||
struct strbuf *out;
|
||||
int use_pack_protocol;
|
||||
int count;
|
||||
};
|
||||
|
||||
static int write_one_shallow(const struct commit_graft *graft, void *cb_data)
|
||||
{
|
||||
struct write_shallow_data *data = cb_data;
|
||||
const char *hex = sha1_to_hex(graft->sha1);
|
||||
data->count++;
|
||||
if (data->use_pack_protocol)
|
||||
packet_buf_write(data->out, "shallow %s", hex);
|
||||
else {
|
||||
strbuf_addstr(data->out, hex);
|
||||
strbuf_addch(data->out, '\n');
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int write_shallow_commits(struct strbuf *out, int use_pack_protocol)
|
||||
{
|
||||
struct write_shallow_data data;
|
||||
data.out = out;
|
||||
data.use_pack_protocol = use_pack_protocol;
|
||||
data.count = 0;
|
||||
for_each_commit_graft(write_one_shallow, &data);
|
||||
return data.count;
|
||||
}
|
||||
|
||||
static enum ack_type get_ack(int fd, unsigned char *result_sha1)
|
||||
{
|
||||
static char line[1000];
|
||||
@ -546,7 +514,7 @@ static void filter_refs(struct ref **refs, int nr_match, char **match)
|
||||
for (ref = *refs; ref; ref = next) {
|
||||
next = ref->next;
|
||||
if (!memcmp(ref->name, "refs/", 5) &&
|
||||
check_refname_format(ref->name + 5, 0))
|
||||
check_ref_format(ref->name + 5))
|
||||
; /* trash */
|
||||
else if (args.fetch_all &&
|
||||
(!args.depth || prefixcmp(ref->name, "refs/tags/") )) {
|
||||
@ -736,12 +704,6 @@ static int get_pack(int xd[2], char **pack_lockfile)
|
||||
}
|
||||
if (*hdr_arg)
|
||||
*av++ = hdr_arg;
|
||||
if (fetch_fsck_objects >= 0
|
||||
? fetch_fsck_objects
|
||||
: transfer_fsck_objects >= 0
|
||||
? transfer_fsck_objects
|
||||
: 0)
|
||||
*av++ = "--strict";
|
||||
*av++ = NULL;
|
||||
|
||||
cmd.in = demux.out;
|
||||
@ -861,16 +823,6 @@ static int fetch_pack_config(const char *var, const char *value, void *cb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(var, "fetch.fsckobjects")) {
|
||||
fetch_fsck_objects = git_config_bool(var, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(var, "transfer.fsckobjects")) {
|
||||
transfer_fsck_objects = git_config_bool(var, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return git_default_config(var, value, cb);
|
||||
}
|
||||
|
||||
|
204
builtin/fetch.c
204
builtin/fetch.c
@ -13,7 +13,6 @@
|
||||
#include "sigchain.h"
|
||||
#include "transport.h"
|
||||
#include "submodule.h"
|
||||
#include "connected.h"
|
||||
|
||||
static const char * const builtin_fetch_usage[] = {
|
||||
"git fetch [<options>] [<repository> [<refspec>...]]",
|
||||
@ -240,23 +239,23 @@ static int s_update_ref(const char *action,
|
||||
|
||||
static int update_local_ref(struct ref *ref,
|
||||
const char *remote,
|
||||
char *display)
|
||||
struct strbuf *display)
|
||||
{
|
||||
struct commit *current = NULL, *updated;
|
||||
enum object_type type;
|
||||
struct branch *current_branch = branch_get(NULL);
|
||||
const char *pretty_ref = prettify_refname(ref->name);
|
||||
|
||||
*display = 0;
|
||||
type = sha1_object_info(ref->new_sha1, NULL);
|
||||
if (type < 0)
|
||||
die(_("object %s not found"), sha1_to_hex(ref->new_sha1));
|
||||
|
||||
if (!hashcmp(ref->old_sha1, ref->new_sha1)) {
|
||||
if (verbosity > 0)
|
||||
sprintf(display, "= %-*s %-*s -> %s", TRANSPORT_SUMMARY_WIDTH,
|
||||
_("[up to date]"), REFCOL_WIDTH, remote,
|
||||
pretty_ref);
|
||||
strbuf_addf(display, "= %-*s %-*s -> %s",
|
||||
TRANSPORT_SUMMARY_WIDTH,
|
||||
_("[up to date]"), REFCOL_WIDTH,
|
||||
remote, pretty_ref);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -268,9 +267,10 @@ static int update_local_ref(struct ref *ref,
|
||||
* If this is the head, and it's not okay to update
|
||||
* the head, and the old value of the head isn't empty...
|
||||
*/
|
||||
sprintf(display, _("! %-*s %-*s -> %s (can't fetch in current branch)"),
|
||||
TRANSPORT_SUMMARY_WIDTH, _("[rejected]"), REFCOL_WIDTH, remote,
|
||||
pretty_ref);
|
||||
strbuf_addf(display,
|
||||
_("! %-*s %-*s -> %s (can't fetch in current branch)"),
|
||||
TRANSPORT_SUMMARY_WIDTH, _("[rejected]"),
|
||||
REFCOL_WIDTH, remote, pretty_ref);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -278,9 +278,11 @@ static int update_local_ref(struct ref *ref,
|
||||
!prefixcmp(ref->name, "refs/tags/")) {
|
||||
int r;
|
||||
r = s_update_ref("updating tag", ref, 0);
|
||||
sprintf(display, "%c %-*s %-*s -> %s%s", r ? '!' : '-',
|
||||
TRANSPORT_SUMMARY_WIDTH, _("[tag update]"), REFCOL_WIDTH, remote,
|
||||
pretty_ref, r ? _(" (unable to update local ref)") : "");
|
||||
strbuf_addf(display, "%c %-*s %-*s -> %s%s",
|
||||
r ? '!' : '-',
|
||||
TRANSPORT_SUMMARY_WIDTH, _("[tag update]"),
|
||||
REFCOL_WIDTH, remote, pretty_ref,
|
||||
r ? _(" (unable to update local ref)") : "");
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -303,9 +305,11 @@ static int update_local_ref(struct ref *ref,
|
||||
}
|
||||
|
||||
r = s_update_ref(msg, ref, 0);
|
||||
sprintf(display, "%c %-*s %-*s -> %s%s", r ? '!' : '*',
|
||||
TRANSPORT_SUMMARY_WIDTH, what, REFCOL_WIDTH, remote, pretty_ref,
|
||||
r ? _(" (unable to update local ref)") : "");
|
||||
strbuf_addf(display, "%c %-*s %-*s -> %s%s",
|
||||
r ? '!' : '*',
|
||||
TRANSPORT_SUMMARY_WIDTH, what,
|
||||
REFCOL_WIDTH, remote, pretty_ref,
|
||||
r ? _(" (unable to update local ref)") : "");
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -319,9 +323,11 @@ static int update_local_ref(struct ref *ref,
|
||||
(recurse_submodules != RECURSE_SUBMODULES_ON))
|
||||
check_for_new_submodule_commits(ref->new_sha1);
|
||||
r = s_update_ref("fast-forward", ref, 1);
|
||||
sprintf(display, "%c %-*s %-*s -> %s%s", r ? '!' : ' ',
|
||||
TRANSPORT_SUMMARY_WIDTH, quickref, REFCOL_WIDTH, remote,
|
||||
pretty_ref, r ? _(" (unable to update local ref)") : "");
|
||||
strbuf_addf(display, "%c %-*s %-*s -> %s%s",
|
||||
r ? '!' : ' ',
|
||||
TRANSPORT_SUMMARY_WIDTH, quickref,
|
||||
REFCOL_WIDTH, remote, pretty_ref,
|
||||
r ? _(" (unable to update local ref)") : "");
|
||||
return r;
|
||||
} else if (force || ref->force) {
|
||||
char quickref[84];
|
||||
@ -333,38 +339,28 @@ static int update_local_ref(struct ref *ref,
|
||||
(recurse_submodules != RECURSE_SUBMODULES_ON))
|
||||
check_for_new_submodule_commits(ref->new_sha1);
|
||||
r = s_update_ref("forced-update", ref, 1);
|
||||
sprintf(display, "%c %-*s %-*s -> %s (%s)", r ? '!' : '+',
|
||||
TRANSPORT_SUMMARY_WIDTH, quickref, REFCOL_WIDTH, remote,
|
||||
pretty_ref,
|
||||
r ? _("unable to update local ref") : _("forced update"));
|
||||
strbuf_addf(display, "%c %-*s %-*s -> %s (%s)",
|
||||
r ? '!' : '+',
|
||||
TRANSPORT_SUMMARY_WIDTH, quickref,
|
||||
REFCOL_WIDTH, remote, pretty_ref,
|
||||
r ? _("unable to update local ref") : _("forced update"));
|
||||
return r;
|
||||
} else {
|
||||
sprintf(display, "! %-*s %-*s -> %s %s",
|
||||
TRANSPORT_SUMMARY_WIDTH, _("[rejected]"), REFCOL_WIDTH, remote,
|
||||
pretty_ref, _("(non-fast-forward)"));
|
||||
strbuf_addf(display, "! %-*s %-*s -> %s %s",
|
||||
TRANSPORT_SUMMARY_WIDTH, _("[rejected]"),
|
||||
REFCOL_WIDTH, remote, pretty_ref,
|
||||
_("(non-fast-forward)"));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int iterate_ref_map(void *cb_data, unsigned char sha1[20])
|
||||
{
|
||||
struct ref **rm = cb_data;
|
||||
struct ref *ref = *rm;
|
||||
|
||||
if (!ref)
|
||||
return -1; /* end of the list */
|
||||
*rm = ref->next;
|
||||
hashcpy(sha1, ref->old_sha1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int store_updated_refs(const char *raw_url, const char *remote_name,
|
||||
struct ref *ref_map)
|
||||
{
|
||||
FILE *fp;
|
||||
struct commit *commit;
|
||||
int url_len, i, note_len, shown_url = 0, rc = 0;
|
||||
char note[1024];
|
||||
int url_len, i, shown_url = 0, rc = 0;
|
||||
struct strbuf note = STRBUF_INIT;
|
||||
const char *what, *kind;
|
||||
struct ref *rm;
|
||||
char *url, *filename = dry_run ? "/dev/null" : git_path("FETCH_HEAD");
|
||||
@ -377,13 +373,6 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
|
||||
url = transport_anonymize_url(raw_url);
|
||||
else
|
||||
url = xstrdup("foreign");
|
||||
|
||||
rm = ref_map;
|
||||
if (check_everything_connected(iterate_ref_map, 0, &rm)) {
|
||||
rc = error(_("%s did not send all necessary objects\n"), url);
|
||||
goto abort;
|
||||
}
|
||||
|
||||
for (rm = ref_map; rm; rm = rm->next) {
|
||||
struct ref *ref = NULL;
|
||||
|
||||
@ -427,19 +416,17 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
|
||||
if (4 < i && !strncmp(".git", url + i - 3, 4))
|
||||
url_len = i - 3;
|
||||
|
||||
note_len = 0;
|
||||
strbuf_reset(¬e);
|
||||
if (*what) {
|
||||
if (*kind)
|
||||
note_len += sprintf(note + note_len, "%s ",
|
||||
kind);
|
||||
note_len += sprintf(note + note_len, "'%s' of ", what);
|
||||
strbuf_addf(¬e, "%s ", kind);
|
||||
strbuf_addf(¬e, "'%s' of ", what);
|
||||
}
|
||||
note[note_len] = '\0';
|
||||
fprintf(fp, "%s\t%s\t%s",
|
||||
sha1_to_hex(commit ? commit->object.sha1 :
|
||||
rm->old_sha1),
|
||||
rm->merge ? "" : "not-for-merge",
|
||||
note);
|
||||
note.buf);
|
||||
for (i = 0; i < url_len; ++i)
|
||||
if ('\n' == url[i])
|
||||
fputs("\\n", fp);
|
||||
@ -447,32 +434,33 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
|
||||
fputc(url[i], fp);
|
||||
fputc('\n', fp);
|
||||
|
||||
strbuf_reset(¬e);
|
||||
if (ref) {
|
||||
rc |= update_local_ref(ref, what, note);
|
||||
rc |= update_local_ref(ref, what, ¬e);
|
||||
free(ref);
|
||||
} else
|
||||
sprintf(note, "* %-*s %-*s -> FETCH_HEAD",
|
||||
TRANSPORT_SUMMARY_WIDTH, *kind ? kind : "branch",
|
||||
REFCOL_WIDTH, *what ? what : "HEAD");
|
||||
if (*note) {
|
||||
strbuf_addf(¬e, "* %-*s %-*s -> FETCH_HEAD",
|
||||
TRANSPORT_SUMMARY_WIDTH,
|
||||
*kind ? kind : "branch",
|
||||
REFCOL_WIDTH,
|
||||
*what ? what : "HEAD");
|
||||
if (note.len) {
|
||||
if (verbosity >= 0 && !shown_url) {
|
||||
fprintf(stderr, _("From %.*s\n"),
|
||||
url_len, url);
|
||||
shown_url = 1;
|
||||
}
|
||||
if (verbosity >= 0)
|
||||
fprintf(stderr, " %s\n", note);
|
||||
fprintf(stderr, " %s\n", note.buf);
|
||||
}
|
||||
}
|
||||
|
||||
free(url);
|
||||
fclose(fp);
|
||||
if (rc & STORE_REF_ERROR_DF_CONFLICT)
|
||||
error(_("some local refs could not be updated; try running\n"
|
||||
" 'git remote prune %s' to remove any old, conflicting "
|
||||
"branches"), remote_name);
|
||||
|
||||
abort:
|
||||
free(url);
|
||||
fclose(fp);
|
||||
strbuf_release(¬e);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -480,10 +468,23 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
|
||||
* We would want to bypass the object transfer altogether if
|
||||
* everything we are going to fetch already exists and is connected
|
||||
* locally.
|
||||
*
|
||||
* The refs we are going to fetch are in ref_map. If running
|
||||
*
|
||||
* $ git rev-list --objects --stdin --not --all
|
||||
*
|
||||
* (feeding all the refs in ref_map on its standard input)
|
||||
* does not error out, that means everything reachable from the
|
||||
* refs we are going to fetch exists and is connected to some of
|
||||
* our existing refs.
|
||||
*/
|
||||
static int quickfetch(struct ref *ref_map)
|
||||
{
|
||||
struct ref *rm = ref_map;
|
||||
struct child_process revlist;
|
||||
struct ref *ref;
|
||||
int err;
|
||||
const char *argv[] = {"rev-list",
|
||||
"--quiet", "--objects", "--stdin", "--not", "--all", NULL};
|
||||
|
||||
/*
|
||||
* If we are deepening a shallow clone we already have these
|
||||
@ -494,7 +495,47 @@ static int quickfetch(struct ref *ref_map)
|
||||
*/
|
||||
if (depth)
|
||||
return -1;
|
||||
return check_everything_connected(iterate_ref_map, 1, &rm);
|
||||
|
||||
if (!ref_map)
|
||||
return 0;
|
||||
|
||||
memset(&revlist, 0, sizeof(revlist));
|
||||
revlist.argv = argv;
|
||||
revlist.git_cmd = 1;
|
||||
revlist.no_stdout = 1;
|
||||
revlist.no_stderr = 1;
|
||||
revlist.in = -1;
|
||||
|
||||
err = start_command(&revlist);
|
||||
if (err) {
|
||||
error(_("could not run rev-list"));
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* If rev-list --stdin encounters an unknown commit, it terminates,
|
||||
* which will cause SIGPIPE in the write loop below.
|
||||
*/
|
||||
sigchain_push(SIGPIPE, SIG_IGN);
|
||||
|
||||
for (ref = ref_map; ref; ref = ref->next) {
|
||||
if (write_in_full(revlist.in, sha1_to_hex(ref->old_sha1), 40) < 0 ||
|
||||
write_str_in_full(revlist.in, "\n") < 0) {
|
||||
if (errno != EPIPE && errno != EINVAL)
|
||||
error(_("failed write to rev-list: %s"), strerror(errno));
|
||||
err = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (close(revlist.in)) {
|
||||
error(_("failed to close rev-list's stdin: %s"), strerror(errno));
|
||||
err = -1;
|
||||
}
|
||||
|
||||
sigchain_pop(SIGPIPE);
|
||||
|
||||
return finish_command(&revlist) || err;
|
||||
}
|
||||
|
||||
static int fetch_refs(struct transport *transport, struct ref *ref_map)
|
||||
@ -510,10 +551,10 @@ static int fetch_refs(struct transport *transport, struct ref *ref_map)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int prune_refs(struct refspec *refs, int ref_count, struct ref *ref_map)
|
||||
static int prune_refs(struct transport *transport, struct ref *ref_map)
|
||||
{
|
||||
int result = 0;
|
||||
struct ref *ref, *stale_refs = get_stale_heads(refs, ref_count, ref_map);
|
||||
struct ref *ref, *stale_refs = get_stale_heads(transport->remote, ref_map);
|
||||
const char *dangling_msg = dry_run
|
||||
? _(" (%s will become dangling)\n")
|
||||
: _(" (%s has become dangling)\n");
|
||||
@ -704,31 +745,8 @@ static int do_fetch(struct transport *transport,
|
||||
free_refs(ref_map);
|
||||
return 1;
|
||||
}
|
||||
if (prune) {
|
||||
/* If --tags was specified, pretend the user gave us the canonical tags refspec */
|
||||
if (tags == TAGS_SET) {
|
||||
const char *tags_str = "refs/tags/*:refs/tags/*";
|
||||
struct refspec *tags_refspec, *refspec;
|
||||
|
||||
/* Copy the refspec and add the tags to it */
|
||||
refspec = xcalloc(ref_count + 1, sizeof(struct refspec));
|
||||
tags_refspec = parse_fetch_refspec(1, &tags_str);
|
||||
memcpy(refspec, refs, ref_count * sizeof(struct refspec));
|
||||
memcpy(&refspec[ref_count], tags_refspec, sizeof(struct refspec));
|
||||
ref_count++;
|
||||
|
||||
prune_refs(refspec, ref_count, ref_map);
|
||||
|
||||
ref_count--;
|
||||
/* The rest of the strings belong to fetch_one */
|
||||
free_refspec(1, tags_refspec);
|
||||
free(refspec);
|
||||
} else if (ref_count) {
|
||||
prune_refs(refs, ref_count, ref_map);
|
||||
} else {
|
||||
prune_refs(transport->remote->fetch, transport->remote->fetch_refspec_nr, ref_map);
|
||||
}
|
||||
}
|
||||
if (prune)
|
||||
prune_refs(transport, ref_map);
|
||||
free_refs(ref_map);
|
||||
|
||||
/* if neither --no-tags nor --tags was specified, do automated tag
|
||||
@ -911,7 +929,7 @@ static int fetch_one(struct remote *remote, int argc, const char **argv)
|
||||
atexit(unlock_pack);
|
||||
refspec = parse_fetch_refspec(ref_nr, refs);
|
||||
exit_code = do_fetch(transport, refspec, ref_nr);
|
||||
free_refspec(ref_nr, refspec);
|
||||
free(refspec);
|
||||
transport_disconnect(transport);
|
||||
transport = NULL;
|
||||
return exit_code;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user