Merge remote branch 'ko/master' into HEAD
* ko/master: (366 commits) Update draft release notes to 1.6.6 before merging topics for -rc1 Makefile: do not clean arm directory Add a notice that only certain functions can print color escape codes builtin-apply.c: pay attention to -p<n> when determining the name gitworkflows: Consistently back-quote git commands Explicitly truncate bswap operand to uint32_t t1200: fix a timing dependent error Documentation: update descriptions of revision options related to '--bisect' Enable support for IPv6 on MinGW Refactor winsock initialization into a separate function t/gitweb-lib: Split HTTP response with non-GNU sed pack-objects: split implications of --all-progress from progress activation instaweb: restart server if already running prune-packed: only show progress when stderr is a tty remote-curl.c: fix rpc_out() Protect scripted Porcelains from GREP_OPTIONS insanity mergetool--lib: simplify guess_merge_tool() strbuf_add_wrapped_text(): skip over colour codes t4014-format-patch: do not assume 'test' is available as non-builtin Fix over-simplified documentation for 'git log -z' ...
This commit is contained in:
commit
44148f2daf
357
.gitignore
vendored
357
.gitignore
vendored
@ -1,184 +1,187 @@
|
|||||||
GIT-BUILD-OPTIONS
|
/GIT-BUILD-OPTIONS
|
||||||
GIT-CFLAGS
|
/GIT-CFLAGS
|
||||||
GIT-GUI-VARS
|
/GIT-GUI-VARS
|
||||||
GIT-VERSION-FILE
|
/GIT-VERSION-FILE
|
||||||
git
|
/git
|
||||||
git-add
|
/git-add
|
||||||
git-add--interactive
|
/git-add--interactive
|
||||||
git-am
|
/git-am
|
||||||
git-annotate
|
/git-annotate
|
||||||
git-apply
|
/git-apply
|
||||||
git-archimport
|
/git-archimport
|
||||||
git-archive
|
/git-archive
|
||||||
git-bisect
|
/git-bisect
|
||||||
git-bisect--helper
|
/git-bisect--helper
|
||||||
git-blame
|
/git-blame
|
||||||
git-branch
|
/git-branch
|
||||||
git-bundle
|
/git-bundle
|
||||||
git-cat-file
|
/git-cat-file
|
||||||
git-check-attr
|
/git-check-attr
|
||||||
git-check-ref-format
|
/git-check-ref-format
|
||||||
git-checkout
|
/git-checkout
|
||||||
git-checkout-index
|
/git-checkout-index
|
||||||
git-cherry
|
/git-cherry
|
||||||
git-cherry-pick
|
/git-cherry-pick
|
||||||
git-clean
|
/git-clean
|
||||||
git-clone
|
/git-clone
|
||||||
git-commit
|
/git-commit
|
||||||
git-commit-tree
|
/git-commit-tree
|
||||||
git-config
|
/git-config
|
||||||
git-count-objects
|
/git-count-objects
|
||||||
git-cvsexportcommit
|
/git-cvsexportcommit
|
||||||
git-cvsimport
|
/git-cvsimport
|
||||||
git-cvsserver
|
/git-cvsserver
|
||||||
git-daemon
|
/git-daemon
|
||||||
git-diff
|
/git-diff
|
||||||
git-diff-files
|
/git-diff-files
|
||||||
git-diff-index
|
/git-diff-index
|
||||||
git-diff-tree
|
/git-diff-tree
|
||||||
git-difftool
|
/git-difftool
|
||||||
git-difftool--helper
|
/git-difftool--helper
|
||||||
git-describe
|
/git-describe
|
||||||
git-fast-export
|
/git-fast-export
|
||||||
git-fast-import
|
/git-fast-import
|
||||||
git-fetch
|
/git-fetch
|
||||||
git-fetch--tool
|
/git-fetch--tool
|
||||||
git-fetch-pack
|
/git-fetch-pack
|
||||||
git-filter-branch
|
/git-filter-branch
|
||||||
git-fmt-merge-msg
|
/git-fmt-merge-msg
|
||||||
git-for-each-ref
|
/git-for-each-ref
|
||||||
git-format-patch
|
/git-format-patch
|
||||||
git-fsck
|
/git-fsck
|
||||||
git-fsck-objects
|
/git-fsck-objects
|
||||||
git-gc
|
/git-gc
|
||||||
git-get-tar-commit-id
|
/git-get-tar-commit-id
|
||||||
git-grep
|
/git-grep
|
||||||
git-hash-object
|
/git-hash-object
|
||||||
git-help
|
/git-help
|
||||||
git-http-fetch
|
/git-http-backend
|
||||||
git-http-push
|
/git-http-fetch
|
||||||
git-imap-send
|
/git-http-push
|
||||||
git-index-pack
|
/git-imap-send
|
||||||
git-init
|
/git-index-pack
|
||||||
git-init-db
|
/git-init
|
||||||
git-instaweb
|
/git-init-db
|
||||||
git-log
|
/git-instaweb
|
||||||
git-lost-found
|
/git-log
|
||||||
git-ls-files
|
/git-lost-found
|
||||||
git-ls-remote
|
/git-ls-files
|
||||||
git-ls-tree
|
/git-ls-remote
|
||||||
git-mailinfo
|
/git-ls-tree
|
||||||
git-mailsplit
|
/git-mailinfo
|
||||||
git-merge
|
/git-mailsplit
|
||||||
git-merge-base
|
/git-merge
|
||||||
git-merge-index
|
/git-merge-base
|
||||||
git-merge-file
|
/git-merge-index
|
||||||
git-merge-tree
|
/git-merge-file
|
||||||
git-merge-octopus
|
/git-merge-tree
|
||||||
git-merge-one-file
|
/git-merge-octopus
|
||||||
git-merge-ours
|
/git-merge-one-file
|
||||||
git-merge-recursive
|
/git-merge-ours
|
||||||
git-merge-resolve
|
/git-merge-recursive
|
||||||
git-merge-subtree
|
/git-merge-resolve
|
||||||
git-mergetool
|
/git-merge-subtree
|
||||||
git-mergetool--lib
|
/git-mergetool
|
||||||
git-mktag
|
/git-mergetool--lib
|
||||||
git-mktree
|
/git-mktag
|
||||||
git-name-rev
|
/git-mktree
|
||||||
git-mv
|
/git-name-rev
|
||||||
git-pack-redundant
|
/git-mv
|
||||||
git-pack-objects
|
/git-notes
|
||||||
git-pack-refs
|
/git-pack-redundant
|
||||||
git-parse-remote
|
/git-pack-objects
|
||||||
git-patch-id
|
/git-pack-refs
|
||||||
git-peek-remote
|
/git-parse-remote
|
||||||
git-prune
|
/git-patch-id
|
||||||
git-prune-packed
|
/git-peek-remote
|
||||||
git-pull
|
/git-prune
|
||||||
git-push
|
/git-prune-packed
|
||||||
git-quiltimport
|
/git-pull
|
||||||
git-read-tree
|
/git-push
|
||||||
git-rebase
|
/git-quiltimport
|
||||||
git-rebase--interactive
|
/git-read-tree
|
||||||
git-receive-pack
|
/git-rebase
|
||||||
git-reflog
|
/git-rebase--interactive
|
||||||
git-relink
|
/git-receive-pack
|
||||||
git-remote
|
/git-reflog
|
||||||
git-remote-curl
|
/git-relink
|
||||||
git-repack
|
/git-remote
|
||||||
git-replace
|
/git-remote-curl
|
||||||
git-repo-config
|
/git-repack
|
||||||
git-request-pull
|
/git-replace
|
||||||
git-rerere
|
/git-repo-config
|
||||||
git-reset
|
/git-request-pull
|
||||||
git-rev-list
|
/git-rerere
|
||||||
git-rev-parse
|
/git-reset
|
||||||
git-revert
|
/git-rev-list
|
||||||
git-rm
|
/git-rev-parse
|
||||||
git-send-email
|
/git-revert
|
||||||
git-send-pack
|
/git-rm
|
||||||
git-sh-setup
|
/git-send-email
|
||||||
git-shell
|
/git-send-pack
|
||||||
git-shortlog
|
/git-sh-setup
|
||||||
git-show
|
/git-shell
|
||||||
git-show-branch
|
/git-shortlog
|
||||||
git-show-index
|
/git-show
|
||||||
git-show-ref
|
/git-show-branch
|
||||||
git-stage
|
/git-show-index
|
||||||
git-stash
|
/git-show-ref
|
||||||
git-status
|
/git-stage
|
||||||
git-stripspace
|
/git-stash
|
||||||
git-submodule
|
/git-status
|
||||||
git-svn
|
/git-stripspace
|
||||||
git-symbolic-ref
|
/git-submodule
|
||||||
git-tag
|
/git-svn
|
||||||
git-tar-tree
|
/git-symbolic-ref
|
||||||
git-unpack-file
|
/git-tag
|
||||||
git-unpack-objects
|
/git-tar-tree
|
||||||
git-update-index
|
/git-unpack-file
|
||||||
git-update-ref
|
/git-unpack-objects
|
||||||
git-update-server-info
|
/git-update-index
|
||||||
git-upload-archive
|
/git-update-ref
|
||||||
git-upload-pack
|
/git-update-server-info
|
||||||
git-var
|
/git-upload-archive
|
||||||
git-verify-pack
|
/git-upload-pack
|
||||||
git-verify-tag
|
/git-var
|
||||||
git-web--browse
|
/git-verify-pack
|
||||||
git-whatchanged
|
/git-verify-tag
|
||||||
git-write-tree
|
/git-web--browse
|
||||||
git-core-*/?*
|
/git-whatchanged
|
||||||
gitk-wish
|
/git-write-tree
|
||||||
gitweb/gitweb.cgi
|
/git-core-*/?*
|
||||||
test-chmtime
|
/gitk-git/gitk-wish
|
||||||
test-ctype
|
/gitweb/gitweb.cgi
|
||||||
test-date
|
/test-chmtime
|
||||||
test-delta
|
/test-ctype
|
||||||
test-dump-cache-tree
|
/test-date
|
||||||
test-genrandom
|
/test-delta
|
||||||
test-match-trees
|
/test-dump-cache-tree
|
||||||
test-parse-options
|
/test-genrandom
|
||||||
test-path-utils
|
/test-match-trees
|
||||||
test-sha1
|
/test-parse-options
|
||||||
test-sigchain
|
/test-path-utils
|
||||||
common-cmds.h
|
/test-sha1
|
||||||
|
/test-sigchain
|
||||||
|
/common-cmds.h
|
||||||
*.tar.gz
|
*.tar.gz
|
||||||
*.dsc
|
*.dsc
|
||||||
*.deb
|
*.deb
|
||||||
git.spec
|
/git.spec
|
||||||
*.exe
|
*.exe
|
||||||
*.[aos]
|
*.[aos]
|
||||||
*.py[co]
|
*.py[co]
|
||||||
config.mak
|
*+
|
||||||
autom4te.cache
|
/config.mak
|
||||||
config.cache
|
/autom4te.cache
|
||||||
config.log
|
/config.cache
|
||||||
config.status
|
/config.log
|
||||||
config.mak.autogen
|
/config.status
|
||||||
config.mak.append
|
/config.mak.autogen
|
||||||
configure
|
/config.mak.append
|
||||||
tags
|
/configure
|
||||||
TAGS
|
/tags
|
||||||
cscope*
|
/TAGS
|
||||||
|
/cscope*
|
||||||
*.obj
|
*.obj
|
||||||
*.lib
|
*.lib
|
||||||
*.sln
|
*.sln
|
||||||
@ -188,5 +191,5 @@ cscope*
|
|||||||
*.user
|
*.user
|
||||||
*.idb
|
*.idb
|
||||||
*.pdb
|
*.pdb
|
||||||
Debug/
|
/Debug/
|
||||||
Release/
|
/Release/
|
||||||
|
@ -103,6 +103,14 @@ ifdef DOCBOOK_SUPPRESS_SP
|
|||||||
XMLTO_EXTRA += -m manpage-suppress-sp.xsl
|
XMLTO_EXTRA += -m manpage-suppress-sp.xsl
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# If your target system uses GNU groff, it may try to render
|
||||||
|
# apostrophes as a "pretty" apostrophe using unicode. This breaks
|
||||||
|
# cut&paste, so you should set GNU_ROFF to force them to be ASCII
|
||||||
|
# apostrophes. Unfortunately does not work with non-GNU roff.
|
||||||
|
ifdef GNU_ROFF
|
||||||
|
XMLTO_EXTRA += -m manpage-quote-apos.xsl
|
||||||
|
endif
|
||||||
|
|
||||||
SHELL_PATH ?= $(SHELL)
|
SHELL_PATH ?= $(SHELL)
|
||||||
# Shell quote;
|
# Shell quote;
|
||||||
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
|
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
|
||||||
|
20
Documentation/RelNotes-1.6.5.1.txt
Normal file
20
Documentation/RelNotes-1.6.5.1.txt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
GIT v1.6.5.1 Release Notes
|
||||||
|
==========================
|
||||||
|
|
||||||
|
Fixes since v1.6.5
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* An corrupt pack could make codepath to read objects into an
|
||||||
|
infinite loop.
|
||||||
|
|
||||||
|
* Download throughput display was always shown in KiB/s but on fast links
|
||||||
|
it is more appropriate to show it in MiB/s.
|
||||||
|
|
||||||
|
* "git grep -f filename" used uninitialized variable and segfaulted.
|
||||||
|
|
||||||
|
* "git clone -b branch" gave a wrong commit object name to post-checkout
|
||||||
|
hook.
|
||||||
|
|
||||||
|
* "git pull" over http did not work on msys.
|
||||||
|
|
||||||
|
Other minor documentation updates are included.
|
19
Documentation/RelNotes-1.6.5.2.txt
Normal file
19
Documentation/RelNotes-1.6.5.2.txt
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
GIT v1.6.5.2 Release Notes
|
||||||
|
==========================
|
||||||
|
|
||||||
|
Fixes since v1.6.5.1
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
* Installation of templates triggered a bug in busybox when using tar
|
||||||
|
implementation from it.
|
||||||
|
|
||||||
|
* "git add -i" incorrectly ignored paths that are already in the index
|
||||||
|
if they matched .gitignore patterns.
|
||||||
|
|
||||||
|
* "git describe --always" should have produced some output even there
|
||||||
|
were no tags in the repository, but it didn't.
|
||||||
|
|
||||||
|
* "git ls-files" when showing tracked files incorrectly paid attention
|
||||||
|
to the exclude patterns.
|
||||||
|
|
||||||
|
Other minor documentation updates are included.
|
63
Documentation/RelNotes-1.6.5.3.txt
Normal file
63
Documentation/RelNotes-1.6.5.3.txt
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
Git v1.6.5.3 Release Notes
|
||||||
|
==========================
|
||||||
|
|
||||||
|
Fixes since v1.6.5.2
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
* info/grafts file didn't ignore trailing CR at the end of lines.
|
||||||
|
|
||||||
|
* Packages generated on newer FC were unreadable by older versions of
|
||||||
|
RPM as the new default is to use stronger hash.
|
||||||
|
|
||||||
|
* output from "git blame" was unreadable when the file ended in an
|
||||||
|
incomplete line.
|
||||||
|
|
||||||
|
* "git add -i/-p" didn't handle deletion of empty files correctly.
|
||||||
|
|
||||||
|
* "git clone" takes up to two parameters, but did not complain when
|
||||||
|
given more arguments than necessary and silently ignored them.
|
||||||
|
|
||||||
|
* "git cvsimport" did not read files given as command line arguments
|
||||||
|
correctly when it is run from a subdirectory.
|
||||||
|
|
||||||
|
* "git diff --color-words -U0" didn't work correctly.
|
||||||
|
|
||||||
|
* The handling of blank lines at the end of file by "git diff/apply
|
||||||
|
--whitespace" was inconsistent with the other kinds of errors.
|
||||||
|
They are now colored, warned against, and fixed the same way as others.
|
||||||
|
|
||||||
|
* There was no way to allow blank lines at the end of file without
|
||||||
|
allowing extra blanks at the end of lines. You can use blank-at-eof
|
||||||
|
and blank-at-eol whitespace error class to specify them separately.
|
||||||
|
The old trailing-space error class is now a short-hand to set both.
|
||||||
|
|
||||||
|
* "-p" option to "git format-patch" was supposed to suppress diffstat
|
||||||
|
generation, but it was broken since 1.6.1.
|
||||||
|
|
||||||
|
* "git imap-send" did not compile cleanly with newer OpenSSL.
|
||||||
|
|
||||||
|
* "git help -a" outside of a git repository was broken.
|
||||||
|
|
||||||
|
* "git ls-files -i" was supposed to be inverse of "git ls-files" without -i
|
||||||
|
with respect to exclude patterns, but it was broken since 1.6.5.2.
|
||||||
|
|
||||||
|
* "git ls-remote" outside of a git repository over http was broken.
|
||||||
|
|
||||||
|
* "git rebase -i" gave bogus error message when the command word was
|
||||||
|
misspelled.
|
||||||
|
|
||||||
|
* "git receive-pack" that is run in response to "git push" did not run
|
||||||
|
garbage collection nor update-server-info, but in larger hosting sites,
|
||||||
|
these almost always need to be run. To help site administrators, the
|
||||||
|
command now runs "gc --auto" and "u-s-i" by setting receive.autogc
|
||||||
|
and receive.updateserverinfo configuration variables, respectively.
|
||||||
|
|
||||||
|
* Release notes spelled the package name with incorrect capitalization.
|
||||||
|
|
||||||
|
* "gitweb" did not escape non-ascii characters correctly in the URL.
|
||||||
|
|
||||||
|
* "gitweb" showed "patch" link even for merge commits.
|
||||||
|
|
||||||
|
* "gitweb" showed incorrect links for blob line numbers in pathinfo mode.
|
||||||
|
|
||||||
|
Other minor documentation updates are included.
|
196
Documentation/RelNotes-1.6.6.txt
Normal file
196
Documentation/RelNotes-1.6.6.txt
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
Git v1.6.6 Release Notes
|
||||||
|
========================
|
||||||
|
|
||||||
|
Notes on behaviour change
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
* In this release, "git fsck" defaults to "git fsck --full" and
|
||||||
|
checks packfiles, and because of this it will take much longer to
|
||||||
|
complete than before. If you prefer a quicker check only on loose
|
||||||
|
objects (the old default), you can say "git fsck --no-full". This
|
||||||
|
has been supported by 1.5.4 and newer versions of git, so it is
|
||||||
|
safe to write it in your script even if you use slightly older git
|
||||||
|
on some of your machines.
|
||||||
|
|
||||||
|
Preparing yourselves for compatibility issues in 1.7.0
|
||||||
|
------------------------------------------------------
|
||||||
|
|
||||||
|
In git 1.7.0, which is planned to be the release after 1.6.6, there will
|
||||||
|
be a handful of behaviour changes that will break backward compatibility.
|
||||||
|
|
||||||
|
These changes were discussed long time ago and existing behaviours have
|
||||||
|
been identified as more problematic to the userbase than keeping them for
|
||||||
|
the sake of backward compatibility.
|
||||||
|
|
||||||
|
When necessary, transition strategy for existing users has been designed
|
||||||
|
not to force them running around setting configuration variables and
|
||||||
|
updating their scripts in order to keep the traditional behaviour on the
|
||||||
|
day their sysadmin decides to install the new version of git. When we
|
||||||
|
switched from "git-foo" to "git foo" in 1.6.0, even though the change had
|
||||||
|
been advertised and the transition guide had been provided for a very long
|
||||||
|
time, the users procrastinated during the entire transtion period, and
|
||||||
|
ended up panicking on the day their sysadmins updated their git.
|
||||||
|
|
||||||
|
For changes decided to be in 1.7.0, we have been much louder to strongly
|
||||||
|
discourage such procrastination. If you have been using recent versions
|
||||||
|
of git, you would have already seen warnings issued when you exercised
|
||||||
|
features whose behaviour will change, with the instruction on how to keep
|
||||||
|
the existing behaviour if you choose to. You hopefully should be well
|
||||||
|
prepared already.
|
||||||
|
|
||||||
|
Of course, we have also given "this and that will change in 1.7.0; prepare
|
||||||
|
yourselves" warnings in the release notes and announcement messages.
|
||||||
|
Let's see how well users will fare this time.
|
||||||
|
|
||||||
|
* "git push" into a branch that is currently checked out (i.e. pointed by
|
||||||
|
HEAD in a repository that is not bare) will be refused by default.
|
||||||
|
|
||||||
|
Similarly, "git push $there :$killed" to delete the branch $killed
|
||||||
|
in a remote repository $there, when $killed branch is the current
|
||||||
|
branch pointed at by its HEAD, will be refused by default.
|
||||||
|
|
||||||
|
Setting the configuration variables receive.denyCurrentBranch and
|
||||||
|
receive.denyDeleteCurrent to 'ignore' in the receiving repository
|
||||||
|
can be used to override these safety features. Versions of git
|
||||||
|
since 1.6.2 have issued a loud warning when you tried to do them
|
||||||
|
without setting the configuration, so repositories of people who
|
||||||
|
still need to be able to perform such a push should already been
|
||||||
|
future proofed.
|
||||||
|
|
||||||
|
Please refer to:
|
||||||
|
|
||||||
|
http://git.or.cz/gitwiki/GitFaq#non-bare
|
||||||
|
http://thread.gmane.org/gmane.comp.version-control.git/107758/focus=108007
|
||||||
|
|
||||||
|
for more details on the reason why this change is needed and the
|
||||||
|
transition process that already took place so far.
|
||||||
|
|
||||||
|
* "git send-email" will not make deep threads by default when sending a
|
||||||
|
patch series with more than two messages. All messages will be sent as
|
||||||
|
a reply to the first message, i.e. cover letter. It has been possible
|
||||||
|
to configure send-email to do this by setting sendemail.chainreplyto
|
||||||
|
configuration variable to false. The only thing the new release will
|
||||||
|
do is to change the default when you haven't configured that variable.
|
||||||
|
|
||||||
|
* "git status" will not be "git commit --dry-run". This change does not
|
||||||
|
affect you if you run the command without pathspec.
|
||||||
|
|
||||||
|
Nobody sane found the current behaviour of "git status Makefile" useful
|
||||||
|
nor meaningful, and it confused users. "git commit --dry-run" has been
|
||||||
|
provided as a way to get the current behaviour of this command since
|
||||||
|
1.6.5.
|
||||||
|
|
||||||
|
* "git diff" traditionally treated various "ignore whitespace" options
|
||||||
|
only as a way to filter the patch output. "git diff --exit-code -b"
|
||||||
|
exited with non-zero status even if all changes were about changing the
|
||||||
|
ammount of whitespace and nothing else. and "git diff -b" showed the
|
||||||
|
"diff --git" header line for such a change without patch text.
|
||||||
|
|
||||||
|
In 1.7.0, the "ignore whitespaces" will affect the semantics of the
|
||||||
|
diff operation itself. A change that does not affect anything but
|
||||||
|
whitespaces will be reported with zero exit status when run with
|
||||||
|
--exit-code, and there will not be "diff --git" header for such a
|
||||||
|
change.
|
||||||
|
|
||||||
|
|
||||||
|
Updates since v1.6.5
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
(subsystems)
|
||||||
|
|
||||||
|
* various git-gui updates including new translations, wm states, etc.
|
||||||
|
|
||||||
|
* git-svn updates.
|
||||||
|
|
||||||
|
* "git fetch" over http learned a new mode that is different from the
|
||||||
|
traditional "dumb commit walker".
|
||||||
|
|
||||||
|
(portability)
|
||||||
|
|
||||||
|
* imap-send can be built on mingw port.
|
||||||
|
|
||||||
|
(performance)
|
||||||
|
|
||||||
|
* "git diff -B" has smaller memory footprint.
|
||||||
|
|
||||||
|
(usability, bells and whistles)
|
||||||
|
|
||||||
|
* The object replace mechanism can be bypassed with --no-replace-objects
|
||||||
|
global option given to the "git" program.
|
||||||
|
|
||||||
|
* In configuration files, a few variables that name paths can begin with ~/
|
||||||
|
and ~username/ and they are expanded as expected.
|
||||||
|
|
||||||
|
* "git subcmd -h" now shows short usage help for many more subcommands.
|
||||||
|
|
||||||
|
* "git bisect reset" can reset to an arbitrary commit.
|
||||||
|
|
||||||
|
* "git checkout frotz" when there is no local branch "frotz" but there
|
||||||
|
is only one remote tracking branch "frotz" is taken as a request to
|
||||||
|
start the named branch at the corresponding remote tracking branch.
|
||||||
|
|
||||||
|
* "git describe" can be told to add "-dirty" suffix with "--dirty" option.
|
||||||
|
|
||||||
|
* "git diff" learned --submodule option to show a list of one-line logs
|
||||||
|
instead of differences between the commit object names.
|
||||||
|
|
||||||
|
* "git fetch" learned --all and --multiple options, to run fetch from
|
||||||
|
many repositories, and --prune option to remove remote tracking
|
||||||
|
branches that went stale. These make "git remote update" and "git
|
||||||
|
remote prune" less necessary (there is no plan to remove "remote
|
||||||
|
update" nor "remote prune", though).
|
||||||
|
|
||||||
|
* "git fsck" by default checks the packfiles (i.e. "--full" is the
|
||||||
|
default); you can turn it off with "git fsck --no-full".
|
||||||
|
|
||||||
|
* "git grep" can use -F (fixed strings) and -i (ignore case) together.
|
||||||
|
|
||||||
|
* import-tars contributed fast-import frontend learned more types of
|
||||||
|
compressed tarballs.
|
||||||
|
|
||||||
|
* "git instaweb" knows how to talk with mod_cgid to apache2.
|
||||||
|
|
||||||
|
* "git log --decorate" shows the location of HEAD as well.
|
||||||
|
|
||||||
|
* "git log" and "git rev-list" learned to take revs and pathspecs from
|
||||||
|
the standard input with the new "--stdin" option.
|
||||||
|
|
||||||
|
* "--pretty=format" option to "log" family of commands learned:
|
||||||
|
|
||||||
|
. to wrap text with the "%w()" specifier.
|
||||||
|
. to show reflog information with "%g[sdD]" specifier.
|
||||||
|
|
||||||
|
* "git notes" command to annotate existing commits.
|
||||||
|
|
||||||
|
* "git merge" (and "git pull") learned --ff-only option to make it fail
|
||||||
|
if the merge does not result in a fast-forward.
|
||||||
|
|
||||||
|
* "git mergetool" learned to use p4merge.
|
||||||
|
|
||||||
|
* "git rebase -i" learned "reword" that acts like "edit" but immediately
|
||||||
|
starts an editor to tweak the log message without returning control to
|
||||||
|
the shell, which is done by "edit" to give an opportunity to tweak the
|
||||||
|
contents.
|
||||||
|
|
||||||
|
* In "git submodule add <repository> <path>", <path> is now optional and
|
||||||
|
inferred from <repository> the same way "git clone <repository>" does.
|
||||||
|
|
||||||
|
* "git svn" learned to read SVN 1.5+ and SVK merge tickets.
|
||||||
|
|
||||||
|
* Author names shown in gitweb output are links to search commits by the
|
||||||
|
author.
|
||||||
|
|
||||||
|
|
||||||
|
(developers)
|
||||||
|
|
||||||
|
Fixes since v1.6.5
|
||||||
|
------------------
|
||||||
|
|
||||||
|
All of the fixes in v1.6.5.X maintenance series are included in this
|
||||||
|
release, unless otherwise noted.
|
||||||
|
|
||||||
|
---
|
||||||
|
exec >/var/tmp/1
|
||||||
|
echo O=$(git describe master)
|
||||||
|
O=v1.6.6-rc0-62-g7fc9d15
|
||||||
|
git shortlog --no-merges $O..master --not maint
|
@ -126,12 +126,20 @@ advice.*::
|
|||||||
Directions on how to stage/unstage/add shown in the
|
Directions on how to stage/unstage/add shown in the
|
||||||
output of linkgit:git-status[1] and the template shown
|
output of linkgit:git-status[1] and the template shown
|
||||||
when writing commit messages. Default: true.
|
when writing commit messages. Default: true.
|
||||||
|
commitBeforeMerge::
|
||||||
|
Advice shown when linkgit:git-merge[1] refuses to
|
||||||
|
merge to avoid overwritting local changes.
|
||||||
|
Default: true.
|
||||||
--
|
--
|
||||||
|
|
||||||
core.fileMode::
|
core.fileMode::
|
||||||
If false, the executable bit differences between the index and
|
If false, the executable bit differences between the index and
|
||||||
the working copy 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]. True by default.
|
See linkgit:git-update-index[1].
|
||||||
|
+
|
||||||
|
The default is true, except linkgit:git-clone[1] or linkgit:git-init[1]
|
||||||
|
will probe and set core.fileMode false if appropriate when the
|
||||||
|
repository is created.
|
||||||
|
|
||||||
core.ignoreCygwinFSTricks::
|
core.ignoreCygwinFSTricks::
|
||||||
This option is only used by Cygwin implementation of Git. If false,
|
This option is only used by Cygwin implementation of Git. If false,
|
||||||
@ -144,6 +152,18 @@ core.ignoreCygwinFSTricks::
|
|||||||
is true, in which case ignoreCygwinFSTricks is ignored as Cygwin's
|
is true, in which case ignoreCygwinFSTricks is ignored as Cygwin's
|
||||||
POSIX emulation is required to support core.filemode.
|
POSIX emulation is required to support core.filemode.
|
||||||
|
|
||||||
|
core.ignorecase::
|
||||||
|
If true, this option enables various workarounds to enable
|
||||||
|
git to work better on filesystems that are not case sensitive,
|
||||||
|
like FAT. For example, if a directory listing finds
|
||||||
|
"makefile" when git expects "Makefile", git will assume
|
||||||
|
it is really the same file, and continue to remember it as
|
||||||
|
"Makefile".
|
||||||
|
+
|
||||||
|
The default is false, except linkgit:git-clone[1] or linkgit:git-init[1]
|
||||||
|
will probe and set core.ignorecase true if appropriate when the repository
|
||||||
|
is created.
|
||||||
|
|
||||||
core.trustctime::
|
core.trustctime::
|
||||||
If false, the ctime differences between the index and the
|
If false, the ctime differences between the index and the
|
||||||
working copy are ignored; useful when the inode change time
|
working copy are ignored; useful when the inode change time
|
||||||
@ -169,9 +189,10 @@ core.autocrlf::
|
|||||||
writing to the filesystem. The variable can be set to
|
writing to the filesystem. The variable can be set to
|
||||||
'input', in which case the conversion happens only while
|
'input', in which case the conversion happens only while
|
||||||
reading from the filesystem but files are written out with
|
reading from the filesystem but files are written out with
|
||||||
`LF` at the end of lines. Currently, which paths to consider
|
`LF` at the end of lines. A file is considered
|
||||||
"text" (i.e. be subjected to the autocrlf mechanism) is
|
"text" (i.e. be subjected to the autocrlf mechanism) based on
|
||||||
decided purely based on the contents.
|
the file's `crlf` attribute, or if `crlf` is unspecified,
|
||||||
|
based on the file's contents. See linkgit:gitattributes[5].
|
||||||
|
|
||||||
core.safecrlf::
|
core.safecrlf::
|
||||||
If true, makes git check if converting `CRLF` as controlled by
|
If true, makes git check if converting `CRLF` as controlled by
|
||||||
@ -223,7 +244,11 @@ core.symlinks::
|
|||||||
contain the link text. linkgit:git-update-index[1] and
|
contain the link text. linkgit:git-update-index[1] and
|
||||||
linkgit:git-add[1] will not change the recorded type to regular
|
linkgit:git-add[1] will not change the recorded type to regular
|
||||||
file. Useful on filesystems like FAT that do not support
|
file. Useful on filesystems like FAT that do not support
|
||||||
symbolic links. True by default.
|
symbolic links.
|
||||||
|
+
|
||||||
|
The default is true, except linkgit:git-clone[1] or linkgit:git-init[1]
|
||||||
|
will probe and set core.symlinks false if appropriate when the repository
|
||||||
|
is created.
|
||||||
|
|
||||||
core.gitProxy::
|
core.gitProxy::
|
||||||
A "proxy command" to execute (as 'command host port') instead
|
A "proxy command" to execute (as 'command host port') instead
|
||||||
@ -380,16 +405,15 @@ Common unit suffixes of 'k', 'm', or 'g' are supported.
|
|||||||
core.excludesfile::
|
core.excludesfile::
|
||||||
In addition to '.gitignore' (per-directory) and
|
In addition to '.gitignore' (per-directory) and
|
||||||
'.git/info/exclude', git looks into this file for patterns
|
'.git/info/exclude', git looks into this file for patterns
|
||||||
of files which are not meant to be tracked. See
|
of files which are not meant to be tracked. "{tilde}/" is expanded
|
||||||
linkgit:gitignore[5].
|
to the value of `$HOME` and "{tilde}user/" to the specified user's
|
||||||
|
home directory. See linkgit:gitignore[5].
|
||||||
|
|
||||||
core.editor::
|
core.editor::
|
||||||
Commands such as `commit` and `tag` that lets you edit
|
Commands such as `commit` and `tag` that lets you edit
|
||||||
messages by launching an editor uses the value of this
|
messages by launching an editor uses the value of this
|
||||||
variable when it is set, and the environment variable
|
variable when it is set, and the environment variable
|
||||||
`GIT_EDITOR` is not set. The order of preference is
|
`GIT_EDITOR` is not set. See linkgit:git-var[1].
|
||||||
`GIT_EDITOR` environment, `core.editor`, `VISUAL` and
|
|
||||||
`EDITOR` environment variables and then finally `vi`.
|
|
||||||
|
|
||||||
core.pager::
|
core.pager::
|
||||||
The command that git will use to paginate output. Can
|
The command that git will use to paginate output. Can
|
||||||
@ -416,13 +440,17 @@ core.whitespace::
|
|||||||
consider them as errors. You can prefix `-` to disable
|
consider them as errors. You can prefix `-` to disable
|
||||||
any of them (e.g. `-trailing-space`):
|
any of them (e.g. `-trailing-space`):
|
||||||
+
|
+
|
||||||
* `trailing-space` treats trailing whitespaces at the end of the line
|
* `blank-at-eol` treats trailing whitespaces at the end of the line
|
||||||
as an error (enabled by default).
|
as an error (enabled by default).
|
||||||
* `space-before-tab` treats a space character that appears immediately
|
* `space-before-tab` treats a space character that appears immediately
|
||||||
before a tab character in the initial indent part of the line as an
|
before a tab character in the initial indent part of the line as an
|
||||||
error (enabled by default).
|
error (enabled by default).
|
||||||
* `indent-with-non-tab` treats a line that is indented with 8 or more
|
* `indent-with-non-tab` treats a line that is indented with 8 or more
|
||||||
space characters as an error (not enabled by default).
|
space characters as an error (not enabled by default).
|
||||||
|
* `blank-at-eof` treats blank lines added at the end of file as an error
|
||||||
|
(enabled by default).
|
||||||
|
* `trailing-space` is a short-hand to cover both `blank-at-eol` and
|
||||||
|
`blank-at-eof`.
|
||||||
* `cr-at-eol` treats a carriage-return at the end of line as
|
* `cr-at-eol` treats a carriage-return at the end of line as
|
||||||
part of the line terminator, i.e. with it, `trailing-space`
|
part of the line terminator, i.e. with it, `trailing-space`
|
||||||
does not trigger if the character before such a carriage-return
|
does not trigger if the character before such a carriage-return
|
||||||
@ -454,6 +482,19 @@ On some file system/operating system combinations, this is unreliable.
|
|||||||
Set this config setting to 'rename' there; However, This will remove the
|
Set this config setting to 'rename' there; However, This will remove the
|
||||||
check that makes sure that existing object files will not get overwritten.
|
check that makes sure that existing object files will not get overwritten.
|
||||||
|
|
||||||
|
core.notesRef::
|
||||||
|
When showing commit messages, also show notes which are stored in
|
||||||
|
the given ref. This ref is expected to contain files named
|
||||||
|
after the full SHA-1 of the commit they annotate.
|
||||||
|
+
|
||||||
|
If such a file exists in the given ref, the referenced blob is read, and
|
||||||
|
appended to the commit message, separated by a "Notes:" line. If the
|
||||||
|
given ref itself does not exist, it is not an error, but means that no
|
||||||
|
notes should be printed.
|
||||||
|
+
|
||||||
|
This setting defaults to "refs/notes/commits", and can be overridden by
|
||||||
|
the `GIT_NOTES_REF` environment variable.
|
||||||
|
|
||||||
add.ignore-errors::
|
add.ignore-errors::
|
||||||
Tells 'git-add' to continue adding files when some files cannot be
|
Tells 'git-add' to continue adding files when some files cannot be
|
||||||
added due to indexing errors. Equivalent to the '--ignore-errors'
|
added due to indexing errors. Equivalent to the '--ignore-errors'
|
||||||
@ -666,6 +707,8 @@ color.ui::
|
|||||||
|
|
||||||
commit.template::
|
commit.template::
|
||||||
Specify a file to use as the template for new commit messages.
|
Specify a file to use as the template for new commit messages.
|
||||||
|
"{tilde}/" is expanded to the value of `$HOME` and "{tilde}user/" to the
|
||||||
|
specified user's home directory.
|
||||||
|
|
||||||
diff.autorefreshindex::
|
diff.autorefreshindex::
|
||||||
When using 'git-diff' to compare with work tree
|
When using 'git-diff' to compare with work tree
|
||||||
@ -1089,6 +1132,14 @@ http.maxRequests::
|
|||||||
How many HTTP requests to launch in parallel. Can be overridden
|
How many HTTP requests to launch in parallel. Can be overridden
|
||||||
by the 'GIT_HTTP_MAX_REQUESTS' environment variable. Default is 5.
|
by the 'GIT_HTTP_MAX_REQUESTS' environment variable. Default is 5.
|
||||||
|
|
||||||
|
http.postBuffer::
|
||||||
|
Maximum size in bytes of the buffer used by smart HTTP
|
||||||
|
transports when POSTing data to the remote system.
|
||||||
|
For requests larger than this buffer size, HTTP/1.1 and
|
||||||
|
Transfer-Encoding: chunked is used to avoid creating a
|
||||||
|
massive pack file locally. Default is 1 MiB, which is
|
||||||
|
sufficient for most requests.
|
||||||
|
|
||||||
http.lowSpeedLimit, http.lowSpeedTime::
|
http.lowSpeedLimit, http.lowSpeedTime::
|
||||||
If the HTTP transfer speed is less than 'http.lowSpeedLimit'
|
If the HTTP transfer speed is less than 'http.lowSpeedLimit'
|
||||||
for longer than 'http.lowSpeedTime' seconds, the transfer is aborted.
|
for longer than 'http.lowSpeedTime' seconds, the transfer is aborted.
|
||||||
@ -1320,6 +1371,11 @@ rebase.stat::
|
|||||||
Whether to show a diffstat of what changed upstream since the last
|
Whether to show a diffstat of what changed upstream since the last
|
||||||
rebase. False by default.
|
rebase. False by default.
|
||||||
|
|
||||||
|
receive.autogc::
|
||||||
|
By default, git-receive-pack will run "git-gc --auto" after
|
||||||
|
receiving data from git-push and updating refs. You can stop
|
||||||
|
it by setting this variable to false.
|
||||||
|
|
||||||
receive.fsckObjects::
|
receive.fsckObjects::
|
||||||
If it is set to true, git-receive-pack will check all received
|
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
|
objects. It will abort in the case of a malformed object or a
|
||||||
@ -1351,10 +1407,14 @@ receive.denyCurrentBranch::
|
|||||||
|
|
||||||
receive.denyNonFastForwards::
|
receive.denyNonFastForwards::
|
||||||
If set to true, git-receive-pack will deny a ref update which is
|
If set to true, git-receive-pack will deny a ref update which is
|
||||||
not a fast forward. Use this to prevent such an update via a push,
|
not a fast-forward. Use this to prevent such an update via a push,
|
||||||
even if that push is forced. This configuration variable is
|
even if that push is forced. This configuration variable is
|
||||||
set when initializing a shared repository.
|
set when initializing a shared repository.
|
||||||
|
|
||||||
|
receive.updateserverinfo::
|
||||||
|
If set to true, git-receive-pack will run git-update-server-info
|
||||||
|
after receiving data from git-push and updating refs.
|
||||||
|
|
||||||
remote.<name>.url::
|
remote.<name>.url::
|
||||||
The URL of a remote repository. See linkgit:git-fetch[1] or
|
The URL of a remote repository. See linkgit:git-fetch[1] or
|
||||||
linkgit:git-push[1].
|
linkgit:git-push[1].
|
||||||
@ -1381,7 +1441,13 @@ remote.<name>.mirror::
|
|||||||
|
|
||||||
remote.<name>.skipDefaultUpdate::
|
remote.<name>.skipDefaultUpdate::
|
||||||
If true, this remote will be skipped by default when updating
|
If true, this remote will be skipped by default when updating
|
||||||
using the update subcommand of linkgit:git-remote[1].
|
using linkgit:git-fetch[1] or the `update` subcommand of
|
||||||
|
linkgit:git-remote[1].
|
||||||
|
|
||||||
|
remote.<name>.skipFetchAll::
|
||||||
|
If true, this remote will be skipped by default when updating
|
||||||
|
using linkgit:git-fetch[1] or the `update` subcommand of
|
||||||
|
linkgit:git-remote[1].
|
||||||
|
|
||||||
remote.<name>.receivepack::
|
remote.<name>.receivepack::
|
||||||
The default program to execute on the remote side when pushing. See
|
The default program to execute on the remote side when pushing. See
|
||||||
|
@ -14,7 +14,8 @@ endif::git-format-patch[]
|
|||||||
|
|
||||||
ifdef::git-format-patch[]
|
ifdef::git-format-patch[]
|
||||||
-p::
|
-p::
|
||||||
Generate patches without diffstat.
|
--no-stat::
|
||||||
|
Generate plain patches without any diffstats.
|
||||||
endif::git-format-patch[]
|
endif::git-format-patch[]
|
||||||
|
|
||||||
ifndef::git-format-patch[]
|
ifndef::git-format-patch[]
|
||||||
@ -27,33 +28,40 @@ endif::git-format-patch[]
|
|||||||
-U<n>::
|
-U<n>::
|
||||||
--unified=<n>::
|
--unified=<n>::
|
||||||
Generate diffs with <n> lines of context instead of
|
Generate diffs with <n> lines of context instead of
|
||||||
the usual three. Implies "-p".
|
the usual three.
|
||||||
|
ifndef::git-format-patch[]
|
||||||
|
Implies `-p`.
|
||||||
|
endif::git-format-patch[]
|
||||||
|
|
||||||
|
ifndef::git-format-patch[]
|
||||||
--raw::
|
--raw::
|
||||||
Generate the raw format.
|
Generate the raw format.
|
||||||
{git-diff-core? This is the default.}
|
{git-diff-core? This is the default.}
|
||||||
|
endif::git-format-patch[]
|
||||||
|
|
||||||
|
ifndef::git-format-patch[]
|
||||||
--patch-with-raw::
|
--patch-with-raw::
|
||||||
Synonym for "-p --raw".
|
Synonym for `-p --raw`.
|
||||||
|
endif::git-format-patch[]
|
||||||
|
|
||||||
--patience::
|
--patience::
|
||||||
Generate a diff using the "patience diff" algorithm.
|
Generate a diff using the "patience diff" algorithm.
|
||||||
|
|
||||||
--stat[=width[,name-width]]::
|
--stat[=width[,name-width]]::
|
||||||
Generate a diffstat. You can override the default
|
Generate a diffstat. You can override the default
|
||||||
output width for 80-column terminal by "--stat=width".
|
output width for 80-column terminal by `--stat=width`.
|
||||||
The width of the filename part can be controlled by
|
The width of the filename part can be controlled by
|
||||||
giving another width to it separated by a comma.
|
giving another width to it separated by a comma.
|
||||||
|
|
||||||
--numstat::
|
--numstat::
|
||||||
Similar to \--stat, but shows number of added and
|
Similar to `\--stat`, but shows number of added and
|
||||||
deleted lines in decimal notation and pathname without
|
deleted lines in decimal notation and pathname without
|
||||||
abbreviation, to make it more machine friendly. For
|
abbreviation, to make it more machine friendly. For
|
||||||
binary files, outputs two `-` instead of saying
|
binary files, outputs two `-` instead of saying
|
||||||
`0 0`.
|
`0 0`.
|
||||||
|
|
||||||
--shortstat::
|
--shortstat::
|
||||||
Output only the last line of the --stat format containing total
|
Output only the last line of the `--stat` format containing total
|
||||||
number of modified files, as well as number of added and deleted
|
number of modified files, as well as number of added and deleted
|
||||||
lines.
|
lines.
|
||||||
|
|
||||||
@ -61,24 +69,39 @@ endif::git-format-patch[]
|
|||||||
Output the distribution of relative amount of changes (number of lines added or
|
Output the distribution of relative amount of changes (number of lines added or
|
||||||
removed) for each sub-directory. Directories with changes below
|
removed) for each sub-directory. Directories with changes below
|
||||||
a cut-off percent (3% by default) are not shown. The cut-off percent
|
a cut-off percent (3% by default) are not shown. The cut-off percent
|
||||||
can be set with "--dirstat=limit". Changes in a child directory is not
|
can be set with `--dirstat=limit`. Changes in a child directory is not
|
||||||
counted for the parent directory, unless "--cumulative" is used.
|
counted for the parent directory, unless `--cumulative` is used.
|
||||||
|
|
||||||
--dirstat-by-file[=limit]::
|
--dirstat-by-file[=limit]::
|
||||||
Same as --dirstat, but counts changed files instead of lines.
|
Same as `--dirstat`, but counts changed files instead of lines.
|
||||||
|
|
||||||
--summary::
|
--summary::
|
||||||
Output a condensed summary of extended header information
|
Output a condensed summary of extended header information
|
||||||
such as creations, renames and mode changes.
|
such as creations, renames and mode changes.
|
||||||
|
|
||||||
|
ifndef::git-format-patch[]
|
||||||
--patch-with-stat::
|
--patch-with-stat::
|
||||||
Synonym for "-p --stat".
|
Synonym for `-p --stat`.
|
||||||
{git-format-patch? This is the default.}
|
endif::git-format-patch[]
|
||||||
|
|
||||||
|
ifndef::git-format-patch[]
|
||||||
|
|
||||||
-z::
|
-z::
|
||||||
NUL-line termination on output. This affects the --raw
|
ifdef::git-log[]
|
||||||
output field terminator. Also output from commands such
|
Separate the commits with NULs instead of with new newlines.
|
||||||
as "git-log" will be delimited with NUL between commits.
|
+
|
||||||
|
Also, when `--raw` or `--numstat` has been given, do not munge
|
||||||
|
pathnames and use NULs as output field terminators.
|
||||||
|
endif::git-log[]
|
||||||
|
ifndef::git-log[]
|
||||||
|
When `--raw` or `--numstat` has been given, do not munge
|
||||||
|
pathnames and use NULs as output field terminators.
|
||||||
|
endif::git-log[]
|
||||||
|
+
|
||||||
|
Without this option, each pathname output will have TAB, LF, double quotes,
|
||||||
|
and backslash characters replaced with `\t`, `\n`, `\"`, and `\\`,
|
||||||
|
respectively, and the pathname will be enclosed in double quotes if
|
||||||
|
any of those replacements occurred.
|
||||||
|
|
||||||
--name-only::
|
--name-only::
|
||||||
Show only names of changed files.
|
Show only names of changed files.
|
||||||
@ -87,6 +110,13 @@ endif::git-format-patch[]
|
|||||||
Show only names and status of changed files. See the description
|
Show only names and status of changed files. See the description
|
||||||
of the `--diff-filter` option on what the status letters mean.
|
of the `--diff-filter` option on what the status letters mean.
|
||||||
|
|
||||||
|
--submodule[=<format>]::
|
||||||
|
Chose the output format for submodule differences. <format> can be one of
|
||||||
|
'short' and 'log'. 'short' just shows pairs of commit names, this format
|
||||||
|
is used when this option is not given. 'log' is the default value for this
|
||||||
|
option and lists the commits in that commit range like the 'summary'
|
||||||
|
option of linkgit:git-submodule[1] does.
|
||||||
|
|
||||||
--color::
|
--color::
|
||||||
Show colored diff.
|
Show colored diff.
|
||||||
|
|
||||||
@ -110,16 +140,19 @@ The regex can also be set via a diff driver or configuration option, see
|
|||||||
linkgit:gitattributes[1] or linkgit:git-config[1]. Giving it explicitly
|
linkgit:gitattributes[1] or linkgit:git-config[1]. Giving it explicitly
|
||||||
overrides any diff driver or configuration setting. Diff drivers
|
overrides any diff driver or configuration setting. Diff drivers
|
||||||
override configuration settings.
|
override configuration settings.
|
||||||
|
endif::git-format-patch[]
|
||||||
|
|
||||||
--no-renames::
|
--no-renames::
|
||||||
Turn off rename detection, even when the configuration
|
Turn off rename detection, even when the configuration
|
||||||
file gives the default to do so.
|
file gives the default to do so.
|
||||||
|
|
||||||
|
ifndef::git-format-patch[]
|
||||||
--check::
|
--check::
|
||||||
Warn if changes introduce trailing whitespace
|
Warn if changes introduce trailing whitespace
|
||||||
or an indent that uses a space before a tab. Exits with
|
or an indent that uses a space before a tab. Exits with
|
||||||
non-zero status if problems are found. Not compatible with
|
non-zero status if problems are found. Not compatible with
|
||||||
--exit-code.
|
--exit-code.
|
||||||
|
endif::git-format-patch[]
|
||||||
|
|
||||||
--full-index::
|
--full-index::
|
||||||
Instead of the first handful of characters, show the full
|
Instead of the first handful of characters, show the full
|
||||||
@ -127,16 +160,16 @@ override configuration settings.
|
|||||||
line when generating patch format output.
|
line when generating patch format output.
|
||||||
|
|
||||||
--binary::
|
--binary::
|
||||||
In addition to --full-index, output "binary diff" that
|
In addition to `--full-index`, output a binary diff that
|
||||||
can be applied with "git apply".
|
can be applied with `git-apply`.
|
||||||
|
|
||||||
--abbrev[=<n>]::
|
--abbrev[=<n>]::
|
||||||
Instead of showing the full 40-byte hexadecimal object
|
Instead of showing the full 40-byte hexadecimal object
|
||||||
name in diff-raw format output and diff-tree header
|
name in diff-raw format output and diff-tree header
|
||||||
lines, show only a partial prefix. This is
|
lines, show only a partial prefix. This is
|
||||||
independent of --full-index option above, which controls
|
independent of the `--full-index` option above, which controls
|
||||||
the diff-patch output format. Non default number of
|
the diff-patch output format. Non default number of
|
||||||
digits can be specified with --abbrev=<n>.
|
digits can be specified with `--abbrev=<n>`.
|
||||||
|
|
||||||
-B::
|
-B::
|
||||||
Break complete rewrite changes into pairs of delete and create.
|
Break complete rewrite changes into pairs of delete and create.
|
||||||
@ -147,6 +180,7 @@ override configuration settings.
|
|||||||
-C::
|
-C::
|
||||||
Detect copies as well as renames. See also `--find-copies-harder`.
|
Detect copies as well as renames. See also `--find-copies-harder`.
|
||||||
|
|
||||||
|
ifndef::git-format-patch[]
|
||||||
--diff-filter=[ACDMRTUXB*]::
|
--diff-filter=[ACDMRTUXB*]::
|
||||||
Select only files that are Added (`A`), Copied (`C`),
|
Select only files that are Added (`A`), Copied (`C`),
|
||||||
Deleted (`D`), Modified (`M`), Renamed (`R`), have their
|
Deleted (`D`), Modified (`M`), Renamed (`R`), have their
|
||||||
@ -158,6 +192,7 @@ override configuration settings.
|
|||||||
paths are selected if there is any file that matches
|
paths are selected if there is any file that matches
|
||||||
other criteria in the comparison; if there is no file
|
other criteria in the comparison; if there is no file
|
||||||
that matches other criteria, nothing is selected.
|
that matches other criteria, nothing is selected.
|
||||||
|
endif::git-format-patch[]
|
||||||
|
|
||||||
--find-copies-harder::
|
--find-copies-harder::
|
||||||
For performance reasons, by default, `-C` option finds copies only
|
For performance reasons, by default, `-C` option finds copies only
|
||||||
@ -169,12 +204,13 @@ override configuration settings.
|
|||||||
`-C` option has the same effect.
|
`-C` option has the same effect.
|
||||||
|
|
||||||
-l<num>::
|
-l<num>::
|
||||||
-M and -C options require O(n^2) processing time where n
|
The `-M` and `-C` options require O(n^2) processing time where n
|
||||||
is the number of potential rename/copy targets. This
|
is the number of potential rename/copy targets. This
|
||||||
option prevents rename/copy detection from running if
|
option prevents rename/copy detection from running if
|
||||||
the number of rename/copy targets exceeds the specified
|
the number of rename/copy targets exceeds the specified
|
||||||
number.
|
number.
|
||||||
|
|
||||||
|
ifndef::git-format-patch[]
|
||||||
-S<string>::
|
-S<string>::
|
||||||
Look for differences that introduce or remove an instance of
|
Look for differences that introduce or remove an instance of
|
||||||
<string>. Note that this is different than the string simply
|
<string>. Note that this is different than the string simply
|
||||||
@ -182,18 +218,20 @@ override configuration settings.
|
|||||||
linkgit:gitdiffcore[7] for more details.
|
linkgit:gitdiffcore[7] for more details.
|
||||||
|
|
||||||
--pickaxe-all::
|
--pickaxe-all::
|
||||||
When -S finds a change, show all the changes in that
|
When `-S` finds a change, show all the changes in that
|
||||||
changeset, not just the files that contain the change
|
changeset, not just the files that contain the change
|
||||||
in <string>.
|
in <string>.
|
||||||
|
|
||||||
--pickaxe-regex::
|
--pickaxe-regex::
|
||||||
Make the <string> not a plain string but an extended POSIX
|
Make the <string> not a plain string but an extended POSIX
|
||||||
regex to match.
|
regex to match.
|
||||||
|
endif::git-format-patch[]
|
||||||
|
|
||||||
-O<orderfile>::
|
-O<orderfile>::
|
||||||
Output the patch in the order specified in the
|
Output the patch in the order specified in the
|
||||||
<orderfile>, which has one shell glob pattern per line.
|
<orderfile>, which has one shell glob pattern per line.
|
||||||
|
|
||||||
|
ifndef::git-format-patch[]
|
||||||
-R::
|
-R::
|
||||||
Swap two inputs; that is, show differences from index or
|
Swap two inputs; that is, show differences from index or
|
||||||
on-disk file to tree contents.
|
on-disk file to tree contents.
|
||||||
@ -205,6 +243,7 @@ override configuration settings.
|
|||||||
not in a subdirectory (e.g. in a bare repository), you
|
not in a subdirectory (e.g. in a bare repository), you
|
||||||
can name which subdirectory to make the output relative
|
can name which subdirectory to make the output relative
|
||||||
to by giving a <path> as an argument.
|
to by giving a <path> as an argument.
|
||||||
|
endif::git-format-patch[]
|
||||||
|
|
||||||
-a::
|
-a::
|
||||||
--text::
|
--text::
|
||||||
@ -229,13 +268,15 @@ override configuration settings.
|
|||||||
Show the context between diff hunks, up to the specified number
|
Show the context between diff hunks, up to the specified number
|
||||||
of lines, thereby fusing hunks that are close to each other.
|
of lines, thereby fusing hunks that are close to each other.
|
||||||
|
|
||||||
|
ifndef::git-format-patch[]
|
||||||
--exit-code::
|
--exit-code::
|
||||||
Make the program exit with codes similar to diff(1).
|
Make the program exit with codes similar to diff(1).
|
||||||
That is, it exits with 1 if there were differences and
|
That is, it exits with 1 if there were differences and
|
||||||
0 means no differences.
|
0 means no differences.
|
||||||
|
|
||||||
--quiet::
|
--quiet::
|
||||||
Disable all output of the program. Implies --exit-code.
|
Disable all output of the program. Implies `--exit-code`.
|
||||||
|
endif::git-format-patch[]
|
||||||
|
|
||||||
--ext-diff::
|
--ext-diff::
|
||||||
Allow an external diff helper to be executed. If you set an
|
Allow an external diff helper to be executed. If you set an
|
||||||
|
@ -1,13 +1,5 @@
|
|||||||
ifndef::git-pull[]
|
--all::
|
||||||
-q::
|
Fetch all remotes.
|
||||||
--quiet::
|
|
||||||
Pass --quiet to git-fetch-pack and silence any other internally
|
|
||||||
used git commands.
|
|
||||||
|
|
||||||
-v::
|
|
||||||
--verbose::
|
|
||||||
Be verbose.
|
|
||||||
endif::git-pull[]
|
|
||||||
|
|
||||||
-a::
|
-a::
|
||||||
--append::
|
--append::
|
||||||
@ -15,11 +7,15 @@ endif::git-pull[]
|
|||||||
existing contents of `.git/FETCH_HEAD`. Without this
|
existing contents of `.git/FETCH_HEAD`. Without this
|
||||||
option old data in `.git/FETCH_HEAD` will be overwritten.
|
option old data in `.git/FETCH_HEAD` will be overwritten.
|
||||||
|
|
||||||
--upload-pack <upload-pack>::
|
--depth=<depth>::
|
||||||
When given, and the repository to fetch from is handled
|
Deepen the history of a 'shallow' repository created by
|
||||||
by 'git-fetch-pack', '--exec=<upload-pack>' is passed to
|
`git clone` with `--depth=<depth>` option (see linkgit:git-clone[1])
|
||||||
the command to specify non-default path for the command
|
by the specified number of commits.
|
||||||
run on the other end.
|
|
||||||
|
ifndef::git-pull[]
|
||||||
|
--dry-run::
|
||||||
|
Show what would be done, without making any changes.
|
||||||
|
endif::git-pull[]
|
||||||
|
|
||||||
-f::
|
-f::
|
||||||
--force::
|
--force::
|
||||||
@ -29,6 +25,20 @@ endif::git-pull[]
|
|||||||
fetches is a descendant of `<lbranch>`. This option
|
fetches is a descendant of `<lbranch>`. This option
|
||||||
overrides that check.
|
overrides that check.
|
||||||
|
|
||||||
|
-k::
|
||||||
|
--keep::
|
||||||
|
Keep downloaded pack.
|
||||||
|
|
||||||
|
ifndef::git-pull[]
|
||||||
|
--multiple::
|
||||||
|
Allow several <repository> and <group> arguments to be
|
||||||
|
specified. No <refspec>s may be specified.
|
||||||
|
|
||||||
|
--prune::
|
||||||
|
After fetching, remove any remote tracking branches which
|
||||||
|
no longer exist on the remote.
|
||||||
|
endif::git-pull[]
|
||||||
|
|
||||||
ifdef::git-pull[]
|
ifdef::git-pull[]
|
||||||
--no-tags::
|
--no-tags::
|
||||||
endif::git-pull[]
|
endif::git-pull[]
|
||||||
@ -49,10 +59,6 @@ endif::git-pull[]
|
|||||||
flag lets all tags and their associated objects be
|
flag lets all tags and their associated objects be
|
||||||
downloaded.
|
downloaded.
|
||||||
|
|
||||||
-k::
|
|
||||||
--keep::
|
|
||||||
Keep downloaded pack.
|
|
||||||
|
|
||||||
-u::
|
-u::
|
||||||
--update-head-ok::
|
--update-head-ok::
|
||||||
By default 'git-fetch' refuses to update the head which
|
By default 'git-fetch' refuses to update the head which
|
||||||
@ -62,7 +68,19 @@ endif::git-pull[]
|
|||||||
implementing your own Porcelain you are not supposed to
|
implementing your own Porcelain you are not supposed to
|
||||||
use it.
|
use it.
|
||||||
|
|
||||||
--depth=<depth>::
|
--upload-pack <upload-pack>::
|
||||||
Deepen the history of a 'shallow' repository created by
|
When given, and the repository to fetch from is handled
|
||||||
`git clone` with `--depth=<depth>` option (see linkgit:git-clone[1])
|
by 'git-fetch-pack', '--exec=<upload-pack>' is passed to
|
||||||
by the specified number of commits.
|
the command to specify non-default path for the command
|
||||||
|
run on the other end.
|
||||||
|
|
||||||
|
ifndef::git-pull[]
|
||||||
|
-q::
|
||||||
|
--quiet::
|
||||||
|
Pass --quiet to git-fetch-pack and silence any other internally
|
||||||
|
used git commands.
|
||||||
|
|
||||||
|
-v::
|
||||||
|
--verbose::
|
||||||
|
Be verbose.
|
||||||
|
endif::git-pull[]
|
||||||
|
@ -76,10 +76,10 @@ OPTIONS
|
|||||||
work tree and add them to the index. This gives the user a chance
|
work tree and add them to the index. This gives the user a chance
|
||||||
to review the difference before adding modified contents to the
|
to review the difference before adding modified contents to the
|
||||||
index.
|
index.
|
||||||
|
+
|
||||||
This effectively runs ``add --interactive``, but bypasses the
|
This effectively runs `add --interactive`, but bypasses the
|
||||||
initial command menu and directly jumps to `patch` subcommand.
|
initial command menu and directly jumps to the `patch` subcommand.
|
||||||
See ``Interactive mode'' for details.
|
See ``Interactive mode'' for details.
|
||||||
|
|
||||||
-e, \--edit::
|
-e, \--edit::
|
||||||
Open the diff vs. the index in an editor and let the user
|
Open the diff vs. the index in an editor and let the user
|
||||||
|
@ -3,7 +3,7 @@ git-apply(1)
|
|||||||
|
|
||||||
NAME
|
NAME
|
||||||
----
|
----
|
||||||
git-apply - Apply a patch on a git index file and/or a working tree
|
git-apply - Apply a patch to files and/or to the index
|
||||||
|
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
@ -20,8 +20,11 @@ SYNOPSIS
|
|||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
Reads supplied 'diff' output and applies it on a git index file
|
Reads the supplied diff output (i.e. "a patch") and applies it to files.
|
||||||
and a work tree.
|
With the `--index` option the patch is also applied to the index, and
|
||||||
|
with the `--cache` option the patch is only applied to the index.
|
||||||
|
Without these options, the command applies the patch only to files,
|
||||||
|
and does not require them to be in a git repository.
|
||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
-------
|
-------
|
||||||
@ -34,7 +37,7 @@ OPTIONS
|
|||||||
input. Turns off "apply".
|
input. Turns off "apply".
|
||||||
|
|
||||||
--numstat::
|
--numstat::
|
||||||
Similar to \--stat, but shows the number of added and
|
Similar to `--stat`, but shows the number of added and
|
||||||
deleted lines in decimal notation and the pathname without
|
deleted lines in decimal notation and the pathname without
|
||||||
abbreviation, to make it more machine friendly. For
|
abbreviation, to make it more machine friendly. For
|
||||||
binary files, outputs two `-` instead of saying
|
binary files, outputs two `-` instead of saying
|
||||||
@ -48,22 +51,22 @@ OPTIONS
|
|||||||
|
|
||||||
--check::
|
--check::
|
||||||
Instead of applying the patch, see if the patch is
|
Instead of applying the patch, see if the patch is
|
||||||
applicable to the current work tree and/or the index
|
applicable to the current working tree and/or the index
|
||||||
file and detects errors. Turns off "apply".
|
file and detects errors. Turns off "apply".
|
||||||
|
|
||||||
--index::
|
--index::
|
||||||
When --check is in effect, or when applying the patch
|
When `--check` is in effect, or when applying the patch
|
||||||
(which is the default when none of the options that
|
(which is the default when none of the options that
|
||||||
disables it is in effect), make sure the patch is
|
disables it is in effect), make sure the patch is
|
||||||
applicable to what the current index file records. If
|
applicable to what the current index file records. If
|
||||||
the file to be patched in the work tree is not
|
the file to be patched in the working tree is not
|
||||||
up-to-date, it is flagged as an error. This flag also
|
up-to-date, it is flagged as an error. This flag also
|
||||||
causes the index file to be updated.
|
causes the index file to be updated.
|
||||||
|
|
||||||
--cached::
|
--cached::
|
||||||
Apply a patch without touching the working tree. Instead take the
|
Apply a patch without touching the working tree. Instead take the
|
||||||
cached data, apply the patch, and store the result in the index
|
cached data, apply the patch, and store the result in the index
|
||||||
without using the working tree. This implies '--index'.
|
without using the working tree. This implies `--index`.
|
||||||
|
|
||||||
--build-fake-ancestor=<file>::
|
--build-fake-ancestor=<file>::
|
||||||
Newer 'git-diff' output has embedded 'index information'
|
Newer 'git-diff' output has embedded 'index information'
|
||||||
@ -87,11 +90,13 @@ the information is read from the current index instead.
|
|||||||
rejected hunks in corresponding *.rej files.
|
rejected hunks in corresponding *.rej files.
|
||||||
|
|
||||||
-z::
|
-z::
|
||||||
When showing the index information, do not munge paths,
|
When `--numstat` has been given, do not munge pathnames,
|
||||||
but use NUL terminated machine readable format. Without
|
but use a NUL-terminated machine-readable format.
|
||||||
this flag, the pathnames output will have TAB, LF, and
|
+
|
||||||
backslash characters replaced with `\t`, `\n`, and `\\`,
|
Without this option, each pathname output will have TAB, LF, double quotes,
|
||||||
respectively.
|
and backslash characters replaced with `\t`, `\n`, `\"`, and `\\`,
|
||||||
|
respectively, and the pathname will be enclosed in double quotes if
|
||||||
|
any of those replacements occurred.
|
||||||
|
|
||||||
-p<n>::
|
-p<n>::
|
||||||
Remove <n> leading slashes from traditional diff paths. The
|
Remove <n> leading slashes from traditional diff paths. The
|
||||||
@ -107,8 +112,8 @@ the information is read from the current index instead.
|
|||||||
By default, 'git-apply' expects that the patch being
|
By default, 'git-apply' expects that the patch being
|
||||||
applied is a unified diff with at least one line of context.
|
applied is a unified diff with at least one line of context.
|
||||||
This provides good safety measures, but breaks down when
|
This provides good safety measures, but breaks down when
|
||||||
applying a diff generated with --unified=0. To bypass these
|
applying a diff generated with `--unified=0`. To bypass these
|
||||||
checks use '--unidiff-zero'.
|
checks use `--unidiff-zero`.
|
||||||
+
|
+
|
||||||
Note, for the reasons stated above usage of context-free patches is
|
Note, for the reasons stated above usage of context-free patches is
|
||||||
discouraged.
|
discouraged.
|
||||||
@ -144,7 +149,7 @@ discouraged.
|
|||||||
be useful when importing patchsets, where you want to include certain
|
be useful when importing patchsets, where you want to include certain
|
||||||
files or directories.
|
files or directories.
|
||||||
+
|
+
|
||||||
When --exclude and --include patterns are used, they are examined in the
|
When `--exclude` and `--include` patterns are used, they are examined in the
|
||||||
order they appear on the command line, and the first match determines if a
|
order they appear on the command line, and the first match determines if a
|
||||||
patch to each path is used. A patch to a path that does not match any
|
patch to each path is used. A patch to a path that does not match any
|
||||||
include/exclude pattern is used by default if there is no include pattern
|
include/exclude pattern is used by default if there is no include pattern
|
||||||
@ -227,13 +232,13 @@ Submodules
|
|||||||
If the patch contains any changes to submodules then 'git-apply'
|
If the patch contains any changes to submodules then 'git-apply'
|
||||||
treats these changes as follows.
|
treats these changes as follows.
|
||||||
|
|
||||||
If --index is specified (explicitly or implicitly), then the submodule
|
If `--index` is specified (explicitly or implicitly), then the submodule
|
||||||
commits must match the index exactly for the patch to apply. If any
|
commits must match the index exactly for the patch to apply. If any
|
||||||
of the submodules are checked-out, then these check-outs are completely
|
of the submodules are checked-out, then these check-outs are completely
|
||||||
ignored, i.e., they are not required to be up-to-date or clean and they
|
ignored, i.e., they are not required to be up-to-date or clean and they
|
||||||
are not updated.
|
are not updated.
|
||||||
|
|
||||||
If --index is not specified, then the submodule commits in the patch
|
If `--index` is not specified, then the submodule commits in the patch
|
||||||
are ignored and only the absence or presence of the corresponding
|
are ignored and only the absence or presence of the corresponding
|
||||||
subdirectory is checked and (if possible) updated.
|
subdirectory is checked and (if possible) updated.
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ on the subcommand:
|
|||||||
git bisect bad [<rev>]
|
git bisect bad [<rev>]
|
||||||
git bisect good [<rev>...]
|
git bisect good [<rev>...]
|
||||||
git bisect skip [(<rev>|<range>)...]
|
git bisect skip [(<rev>|<range>)...]
|
||||||
git bisect reset [<branch>]
|
git bisect reset [<commit>]
|
||||||
git bisect visualize
|
git bisect visualize
|
||||||
git bisect replay <logfile>
|
git bisect replay <logfile>
|
||||||
git bisect log
|
git bisect log
|
||||||
@ -81,16 +81,27 @@ will have been left with the first bad kernel revision in "refs/bisect/bad".
|
|||||||
Bisect reset
|
Bisect reset
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
To return to the original head after a bisect session, issue the
|
After a bisect session, to clean up the bisection state and return to
|
||||||
following command:
|
the original HEAD, issue the following command:
|
||||||
|
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
$ git bisect reset
|
$ git bisect reset
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
This resets the tree to the original branch instead of being on the
|
By default, this will return your tree to the commit that was checked
|
||||||
bisection commit ("git bisect start" will also do that, as it resets
|
out before `git bisect start`. (A new `git bisect start` will also do
|
||||||
the bisection state).
|
that, as it cleans up the old bisection state.)
|
||||||
|
|
||||||
|
With an optional argument, you can return to a different commit
|
||||||
|
instead:
|
||||||
|
|
||||||
|
------------------------------------------------
|
||||||
|
$ git bisect reset <commit>
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
For example, `git bisect reset HEAD` will leave you on the current
|
||||||
|
bisection commit and avoid switching commits at all, while `git bisect
|
||||||
|
reset bisect/bad` will check out the first bad revision.
|
||||||
|
|
||||||
Bisect visualize
|
Bisect visualize
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
|
@ -9,7 +9,8 @@ SYNOPSIS
|
|||||||
--------
|
--------
|
||||||
[verse]
|
[verse]
|
||||||
'git check-ref-format' <refname>
|
'git check-ref-format' <refname>
|
||||||
'git check-ref-format' [--branch] <branchname-shorthand>
|
'git check-ref-format' --print <refname>
|
||||||
|
'git check-ref-format' --branch <branchname-shorthand>
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
@ -63,16 +64,31 @@ reference name expressions (see linkgit:git-rev-parse[1]):
|
|||||||
|
|
||||||
. at-open-brace `@{` is used as a notation to access a reflog entry.
|
. at-open-brace `@{` is used as a notation to access a reflog entry.
|
||||||
|
|
||||||
With the `--branch` option, it expands a branch name shorthand and
|
With the `--print` option, if 'refname' is acceptable, it prints the
|
||||||
prints the name of the branch the shorthand refers to.
|
canonicalized name of a hypothetical reference with that name. That is,
|
||||||
|
it prints 'refname' with any extra `/` characters removed.
|
||||||
|
|
||||||
EXAMPLE
|
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.
|
||||||
|
|
||||||
git check-ref-format --branch @{-1}::
|
EXAMPLES
|
||||||
|
--------
|
||||||
|
|
||||||
Print the name of the previous branch.
|
* Print the name of the previous branch:
|
||||||
|
+
|
||||||
|
------------
|
||||||
|
$ git check-ref-format --branch @{-1}
|
||||||
|
------------
|
||||||
|
|
||||||
|
* Determine the reference name to use for a new branch:
|
||||||
|
+
|
||||||
|
------------
|
||||||
|
$ ref=$(git check-ref-format --print "refs/heads/$newbranch") ||
|
||||||
|
die "we do not like '$newbranch' as a branch name."
|
||||||
|
------------
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
---
|
---
|
||||||
|
@ -39,7 +39,7 @@ OPTIONS
|
|||||||
--local::
|
--local::
|
||||||
-l::
|
-l::
|
||||||
When the repository to clone from is on a local machine,
|
When the repository to clone from is on a local machine,
|
||||||
this flag bypasses normal "git aware" transport
|
this flag bypasses the normal "git aware" transport
|
||||||
mechanism and clones the repository by making a copy of
|
mechanism and clones the repository by making a copy of
|
||||||
HEAD and everything under objects and refs directories.
|
HEAD and everything under objects and refs directories.
|
||||||
The files under `.git/objects/` directory are hardlinked
|
The files under `.git/objects/` directory are hardlinked
|
||||||
@ -60,7 +60,7 @@ OPTIONS
|
|||||||
-s::
|
-s::
|
||||||
When the repository to clone is on the local machine,
|
When the repository to clone is on the local machine,
|
||||||
instead of using hard links, automatically setup
|
instead of using hard links, automatically setup
|
||||||
.git/objects/info/alternates to share the objects
|
`.git/objects/info/alternates` to share the objects
|
||||||
with the source repository. The resulting repository
|
with the source repository. The resulting repository
|
||||||
starts out without any object of its own.
|
starts out without any object of its own.
|
||||||
+
|
+
|
||||||
@ -69,7 +69,7 @@ it unless you understand what it does. If you clone your
|
|||||||
repository using this option and then delete branches (or use any
|
repository using this option and then delete branches (or use any
|
||||||
other git command that makes any existing commit unreferenced) in the
|
other git command that makes any existing commit unreferenced) in the
|
||||||
source repository, some objects may become unreferenced (or dangling).
|
source repository, some objects may become unreferenced (or dangling).
|
||||||
These objects may be removed by normal git operations (such as 'git-commit')
|
These objects may be removed by normal git operations (such as `git commit`)
|
||||||
which automatically call `git gc --auto`. (See linkgit:git-gc[1].)
|
which automatically call `git gc --auto`. (See linkgit:git-gc[1].)
|
||||||
If these objects are removed and were referenced by the cloned repository,
|
If these objects are removed and were referenced by the cloned repository,
|
||||||
then the cloned repository will become corrupt.
|
then the cloned repository will become corrupt.
|
||||||
@ -86,13 +86,13 @@ objects from the source repository into a pack in the cloned repository.
|
|||||||
|
|
||||||
--reference <repository>::
|
--reference <repository>::
|
||||||
If the reference repository is on the local machine,
|
If the reference repository is on the local machine,
|
||||||
automatically setup .git/objects/info/alternates to
|
automatically setup `.git/objects/info/alternates` to
|
||||||
obtain objects from the reference repository. Using
|
obtain objects from the reference repository. Using
|
||||||
an already existing repository as an alternate will
|
an already existing repository as an alternate will
|
||||||
require fewer objects to be copied from the repository
|
require fewer objects to be copied from the repository
|
||||||
being cloned, reducing network and local storage costs.
|
being cloned, reducing network and local storage costs.
|
||||||
+
|
+
|
||||||
*NOTE*: see NOTE to --shared option.
|
*NOTE*: see the NOTE for the `--shared` option.
|
||||||
|
|
||||||
--quiet::
|
--quiet::
|
||||||
-q::
|
-q::
|
||||||
@ -101,7 +101,7 @@ objects from the source repository into a pack in the cloned repository.
|
|||||||
|
|
||||||
--verbose::
|
--verbose::
|
||||||
-v::
|
-v::
|
||||||
Display the progressbar, even in case the standard output is not
|
Display the progress bar, even in case the standard output is not
|
||||||
a terminal.
|
a terminal.
|
||||||
|
|
||||||
--no-checkout::
|
--no-checkout::
|
||||||
@ -121,17 +121,17 @@ objects from the source repository into a pack in the cloned repository.
|
|||||||
configuration variables are created.
|
configuration variables are created.
|
||||||
|
|
||||||
--mirror::
|
--mirror::
|
||||||
Set up a mirror of the remote repository. This implies --bare.
|
Set up a mirror of the remote repository. This implies `--bare`.
|
||||||
|
|
||||||
--origin <name>::
|
--origin <name>::
|
||||||
-o <name>::
|
-o <name>::
|
||||||
Instead of using the remote name 'origin' to keep track
|
Instead of using the remote name `origin` to keep track
|
||||||
of the upstream repository, use <name>.
|
of the upstream repository, use `<name>`.
|
||||||
|
|
||||||
--branch <name>::
|
--branch <name>::
|
||||||
-b <name>::
|
-b <name>::
|
||||||
Instead of pointing the newly created HEAD to the branch pointed
|
Instead of pointing the newly created HEAD to the branch pointed
|
||||||
to by the cloned repository's HEAD, point to <name> branch
|
to by the cloned repository's HEAD, point to `<name>` branch
|
||||||
instead. In a non-bare repository, this is the branch that will
|
instead. In a non-bare repository, this is the branch that will
|
||||||
be checked out.
|
be checked out.
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ objects from the source repository into a pack in the cloned repository.
|
|||||||
--recursive::
|
--recursive::
|
||||||
After the clone is created, initialize all submodules within,
|
After the clone is created, initialize all submodules within,
|
||||||
using their default settings. This is equivalent to running
|
using their default settings. This is equivalent to running
|
||||||
'git submodule update --init --recursive' immediately after
|
`git submodule update --init --recursive` immediately after
|
||||||
the clone is finished. This option is ignored if the cloned
|
the clone is finished. This option is ignored if the cloned
|
||||||
repository does not have a worktree/checkout (i.e. if any of
|
repository does not have a worktree/checkout (i.e. if any of
|
||||||
`--no-checkout`/`-n`, `--bare`, or `--mirror` is given)
|
`--no-checkout`/`-n`, `--bare`, or `--mirror` is given)
|
||||||
@ -171,8 +171,8 @@ objects from the source repository into a pack in the cloned repository.
|
|||||||
<directory>::
|
<directory>::
|
||||||
The name of a new directory to clone into. The "humanish"
|
The name of a new directory to clone into. The "humanish"
|
||||||
part of the source repository is used if no directory is
|
part of the source repository is used if no directory is
|
||||||
explicitly given ("repo" for "/path/to/repo.git" and "foo"
|
explicitly given (`repo` for `/path/to/repo.git` and `foo`
|
||||||
for "host.xz:foo/.git"). Cloning into an existing directory
|
for `host.xz:foo/.git`). Cloning into an existing directory
|
||||||
is only allowed if the directory is empty.
|
is only allowed if the directory is empty.
|
||||||
|
|
||||||
:git-clone: 1
|
:git-clone: 1
|
||||||
|
@ -323,7 +323,7 @@ ENVIRONMENT AND CONFIGURATION VARIABLES
|
|||||||
The editor used to edit the commit log message will be chosen from the
|
The editor used to edit the commit log message will be chosen from the
|
||||||
GIT_EDITOR environment variable, the core.editor configuration variable, the
|
GIT_EDITOR environment variable, the core.editor configuration variable, the
|
||||||
VISUAL environment variable, or the EDITOR environment variable (in that
|
VISUAL environment variable, or the EDITOR environment variable (in that
|
||||||
order).
|
order). See linkgit:git-var[1] for details.
|
||||||
|
|
||||||
HOOKS
|
HOOKS
|
||||||
-----
|
-----
|
||||||
|
@ -182,10 +182,9 @@ Database Backend
|
|||||||
----------------
|
----------------
|
||||||
|
|
||||||
'git-cvsserver' uses one database per git head (i.e. CVS module) to
|
'git-cvsserver' uses one database per git head (i.e. CVS module) to
|
||||||
store information about the repository for faster access. The
|
store information about the repository to maintain consistent
|
||||||
database doesn't contain any persistent data and can be completely
|
CVS revision numbers. The database needs to be
|
||||||
regenerated from the git repository at any time. The database
|
updated (i.e. written to) after every commit.
|
||||||
needs to be updated (i.e. written to) after every commit.
|
|
||||||
|
|
||||||
If the commit is done directly by using `git` (as opposed to
|
If the commit is done directly by using `git` (as opposed to
|
||||||
using 'git-cvsserver') the update will need to happen on the
|
using 'git-cvsserver') the update will need to happen on the
|
||||||
@ -204,6 +203,18 @@ write so it might not be enough to grant the users using
|
|||||||
'git-cvsserver' write access to the database file without granting
|
'git-cvsserver' write access to the database file without granting
|
||||||
them write access to the directory, too.
|
them write access to the directory, too.
|
||||||
|
|
||||||
|
The database can not be reliably regenerated in a
|
||||||
|
consistent form after the branch it is tracking has changed.
|
||||||
|
Example: For merged branches, 'git-cvsserver' only tracks
|
||||||
|
one branch of development, and after a 'git-merge' an
|
||||||
|
incrementally updated database may track a different branch
|
||||||
|
than a database regenerated from scratch, causing inconsistent
|
||||||
|
CVS revision numbers. `git-cvsserver` has no way of knowing which
|
||||||
|
branch it would have picked if it had been run incrementally
|
||||||
|
pre-merge. So if you have to fully or partially (from old
|
||||||
|
backup) regenerate the database, you should be suspicious
|
||||||
|
of pre-existing CVS sandboxes.
|
||||||
|
|
||||||
You can configure the database backend with the following
|
You can configure the database backend with the following
|
||||||
configuration variables:
|
configuration variables:
|
||||||
|
|
||||||
|
@ -8,7 +8,9 @@ git-describe - Show the most recent tag that is reachable from a commit
|
|||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
|
[verse]
|
||||||
'git describe' [--all] [--tags] [--contains] [--abbrev=<n>] <committish>...
|
'git describe' [--all] [--tags] [--contains] [--abbrev=<n>] <committish>...
|
||||||
|
'git describe' [--all] [--tags] [--contains] [--abbrev=<n>] --dirty[=<mark>]
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
@ -27,6 +29,11 @@ OPTIONS
|
|||||||
<committish>...::
|
<committish>...::
|
||||||
Committish object names to describe.
|
Committish object names to describe.
|
||||||
|
|
||||||
|
--dirty[=<mark>]::
|
||||||
|
Describe the working tree.
|
||||||
|
It means describe HEAD and appends <mark> (`-dirty` by
|
||||||
|
default) if the working tree is dirty.
|
||||||
|
|
||||||
--all::
|
--all::
|
||||||
Instead of using only the annotated tags, use any ref
|
Instead of using only the annotated tags, use any ref
|
||||||
found in `.git/refs/`. This option enables matching
|
found in `.git/refs/`. This option enables matching
|
||||||
@ -44,7 +51,9 @@ OPTIONS
|
|||||||
|
|
||||||
--abbrev=<n>::
|
--abbrev=<n>::
|
||||||
Instead of using the default 7 hexadecimal digits as the
|
Instead of using the default 7 hexadecimal digits as the
|
||||||
abbreviated object name, use <n> digits.
|
abbreviated object name, use <n> digits, or as many digits
|
||||||
|
as needed to form a unique object name. An <n> of 0
|
||||||
|
will suppress long format, only showing the closest tag.
|
||||||
|
|
||||||
--candidates=<n>::
|
--candidates=<n>::
|
||||||
Instead of considering only the 10 most recent tags as
|
Instead of considering only the 10 most recent tags as
|
||||||
@ -68,8 +77,8 @@ OPTIONS
|
|||||||
This is useful when you want to see parts of the commit object name
|
This is useful when you want to see parts of the commit object name
|
||||||
in "describe" output, even when the commit in question happens to be
|
in "describe" output, even when the commit in question happens to be
|
||||||
a tagged version. Instead of just emitting the tag name, it will
|
a tagged version. Instead of just emitting the tag name, it will
|
||||||
describe such a commit as v1.2-0-deadbeef (0th commit since tag v1.2
|
describe such a commit as v1.2-0-gdeadbee (0th commit since tag v1.2
|
||||||
that points at object deadbeef....).
|
that points at object deadbee....).
|
||||||
|
|
||||||
--match <pattern>::
|
--match <pattern>::
|
||||||
Only consider tags matching the given pattern (can be used to avoid
|
Only consider tags matching the given pattern (can be used to avoid
|
||||||
@ -108,7 +117,7 @@ the output shows the reference path as well:
|
|||||||
[torvalds@g5 git]$ git describe --all --abbrev=4 v1.0.5^2
|
[torvalds@g5 git]$ git describe --all --abbrev=4 v1.0.5^2
|
||||||
tags/v1.0.0-21-g975b
|
tags/v1.0.0-21-g975b
|
||||||
|
|
||||||
[torvalds@g5 git]$ git describe --all HEAD^
|
[torvalds@g5 git]$ git describe --all --abbrev=4 HEAD^
|
||||||
heads/lt/describe-7-g975b
|
heads/lt/describe-7-g975b
|
||||||
|
|
||||||
With --abbrev set to 0, the command can be used to find the
|
With --abbrev set to 0, the command can be used to find the
|
||||||
@ -117,6 +126,13 @@ closest tagname without any suffix:
|
|||||||
[torvalds@g5 git]$ git describe --abbrev=0 v1.0.5^2
|
[torvalds@g5 git]$ git describe --abbrev=0 v1.0.5^2
|
||||||
tags/v1.0.0
|
tags/v1.0.0
|
||||||
|
|
||||||
|
Note that the suffix you get if you type these commands today may be
|
||||||
|
longer than what Linus saw above when he ran these commands, as your
|
||||||
|
git repository may have new commits whose object names begin with
|
||||||
|
975b that did not exist back then, and "-g975b" suffix alone may not
|
||||||
|
be sufficient to disambiguate these commits.
|
||||||
|
|
||||||
|
|
||||||
SEARCH STRATEGY
|
SEARCH STRATEGY
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ OPTIONS
|
|||||||
Use the diff tool specified by <tool>.
|
Use the diff tool specified by <tool>.
|
||||||
Valid merge tools are:
|
Valid merge tools are:
|
||||||
kdiff3, kompare, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff,
|
kdiff3, kompare, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff,
|
||||||
ecmerge, diffuse, opendiff and araxis.
|
ecmerge, diffuse, opendiff, p4merge and araxis.
|
||||||
+
|
+
|
||||||
If a diff tool is not specified, 'git-difftool'
|
If a diff tool is not specified, 'git-difftool'
|
||||||
will use the configuration variable `diff.tool`. If the
|
will use the configuration variable `diff.tool`. If the
|
||||||
|
@ -316,7 +316,7 @@ change to the project.
|
|||||||
data
|
data
|
||||||
('from' SP <committish> LF)?
|
('from' SP <committish> LF)?
|
||||||
('merge' SP <committish> LF)?
|
('merge' SP <committish> LF)?
|
||||||
(filemodify | filedelete | filecopy | filerename | filedeleteall)*
|
(filemodify | filedelete | filecopy | filerename | filedeleteall | notemodify)*
|
||||||
LF?
|
LF?
|
||||||
....
|
....
|
||||||
|
|
||||||
@ -339,14 +339,13 @@ commit message use a 0 length data. Commit messages are free-form
|
|||||||
and are not interpreted by Git. Currently they must be encoded in
|
and are not interpreted by Git. Currently they must be encoded in
|
||||||
UTF-8, as fast-import does not permit other encodings to be specified.
|
UTF-8, as fast-import does not permit other encodings to be specified.
|
||||||
|
|
||||||
Zero or more `filemodify`, `filedelete`, `filecopy`, `filerename`
|
Zero or more `filemodify`, `filedelete`, `filecopy`, `filerename`,
|
||||||
and `filedeleteall` commands
|
`filedeleteall` and `notemodify` commands
|
||||||
may be included to update the contents of the branch prior to
|
may be included to update the contents of the branch prior to
|
||||||
creating the commit. These commands may be supplied in any order.
|
creating the commit. These commands may be supplied in any order.
|
||||||
However it is recommended that a `filedeleteall` command precede
|
However it is recommended that a `filedeleteall` command precede
|
||||||
all `filemodify`, `filecopy` and `filerename` commands in the same
|
all `filemodify`, `filecopy`, `filerename` and `notemodify` commands in
|
||||||
commit, as `filedeleteall`
|
the same commit, as `filedeleteall` wipes the branch clean (see below).
|
||||||
wipes the branch clean (see below).
|
|
||||||
|
|
||||||
The `LF` after the command is optional (it used to be required).
|
The `LF` after the command is optional (it used to be required).
|
||||||
|
|
||||||
@ -595,6 +594,40 @@ more memory per active branch (less than 1 MiB for even most large
|
|||||||
projects); so frontends that can easily obtain only the affected
|
projects); so frontends that can easily obtain only the affected
|
||||||
paths for a commit are encouraged to do so.
|
paths for a commit are encouraged to do so.
|
||||||
|
|
||||||
|
`notemodify`
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
Included in a `commit` command to add a new note (annotating a given
|
||||||
|
commit) or change the content of an existing note. This command has
|
||||||
|
two different means of specifying the content of the note.
|
||||||
|
|
||||||
|
External data format::
|
||||||
|
The data content for the note was already supplied by a prior
|
||||||
|
`blob` command. The frontend just needs to connect it to the
|
||||||
|
commit that is to be annotated.
|
||||||
|
+
|
||||||
|
....
|
||||||
|
'N' SP <dataref> SP <committish> LF
|
||||||
|
....
|
||||||
|
+
|
||||||
|
Here `<dataref>` can be either a mark reference (`:<idnum>`)
|
||||||
|
set by a prior `blob` command, or a full 40-byte SHA-1 of an
|
||||||
|
existing Git blob object.
|
||||||
|
|
||||||
|
Inline data format::
|
||||||
|
The data content for the note has not been supplied yet.
|
||||||
|
The frontend wants to supply it as part of this modify
|
||||||
|
command.
|
||||||
|
+
|
||||||
|
....
|
||||||
|
'N' SP 'inline' SP <committish> LF
|
||||||
|
data
|
||||||
|
....
|
||||||
|
+
|
||||||
|
See below for a detailed description of the `data` command.
|
||||||
|
|
||||||
|
In both formats `<committish>` is any of the commit specification
|
||||||
|
expressions also accepted by `from` (see above).
|
||||||
|
|
||||||
`mark`
|
`mark`
|
||||||
~~~~~~
|
~~~~~~
|
||||||
Arranges for fast-import to save a reference to the current object, allowing
|
Arranges for fast-import to save a reference to the current object, allowing
|
||||||
|
@ -10,11 +10,17 @@ SYNOPSIS
|
|||||||
--------
|
--------
|
||||||
'git fetch' <options> <repository> <refspec>...
|
'git fetch' <options> <repository> <refspec>...
|
||||||
|
|
||||||
|
'git fetch' <options> <group>
|
||||||
|
|
||||||
|
'git fetch' --multiple <options> [<repository> | <group>]...
|
||||||
|
|
||||||
|
'git fetch' --all <options>
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
Fetches named heads or tags from another repository, along with
|
Fetches named heads or tags from one or more other repositories,
|
||||||
the objects necessary to complete them.
|
along with the objects necessary to complete them.
|
||||||
|
|
||||||
The ref names and their object names of fetched refs are stored
|
The ref names and their object names of fetched refs are stored
|
||||||
in `.git/FETCH_HEAD`. This information is left for a later merge
|
in `.git/FETCH_HEAD`. This information is left for a later merge
|
||||||
@ -28,6 +34,10 @@ pointed by remote tags that it does not yet have, then fetch
|
|||||||
those missing tags. If the other end has tags that point at
|
those missing tags. If the other end has tags that point at
|
||||||
branches you are not interested in, you will not get them.
|
branches you are not interested in, you will not get them.
|
||||||
|
|
||||||
|
'git fetch' can fetch from either a single named repository, or
|
||||||
|
or from several repositories at once if <group> is given and
|
||||||
|
there is a remotes.<group> entry in the configuration file.
|
||||||
|
(See linkgit:git-config[1]).
|
||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
-------
|
-------
|
||||||
@ -37,6 +47,35 @@ include::pull-fetch-param.txt[]
|
|||||||
|
|
||||||
include::urls-remotes.txt[]
|
include::urls-remotes.txt[]
|
||||||
|
|
||||||
|
|
||||||
|
EXAMPLES
|
||||||
|
--------
|
||||||
|
|
||||||
|
* Update the remote-tracking branches:
|
||||||
|
+
|
||||||
|
------------------------------------------------
|
||||||
|
$ git fetch origin
|
||||||
|
------------------------------------------------
|
||||||
|
+
|
||||||
|
The above command copies all branches from the remote refs/heads/
|
||||||
|
namespace and stores them to the local refs/remotes/origin/ namespace,
|
||||||
|
unless the branch.<name>.fetch option is used to specify a non-default
|
||||||
|
refspec.
|
||||||
|
|
||||||
|
* Using refspecs explicitly:
|
||||||
|
+
|
||||||
|
------------------------------------------------
|
||||||
|
$ git fetch origin +pu:pu maint:tmp
|
||||||
|
------------------------------------------------
|
||||||
|
+
|
||||||
|
This updates (or creates, as necessary) branches `pu` and `tmp` in
|
||||||
|
the local repository by fetching from the branches (respectively)
|
||||||
|
`pu` and `maint` from the remote repository.
|
||||||
|
+
|
||||||
|
The `pu` branch will be updated even if it is does not fast-forward,
|
||||||
|
because it is prefixed with a plus sign; `tmp` will not be.
|
||||||
|
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
--------
|
--------
|
||||||
linkgit:git-pull[1]
|
linkgit:git-pull[1]
|
||||||
|
@ -159,7 +159,18 @@ to other tags will be rewritten to point to the underlying commit.
|
|||||||
--subdirectory-filter <directory>::
|
--subdirectory-filter <directory>::
|
||||||
Only look at the history which touches the given subdirectory.
|
Only look at the history which touches the given subdirectory.
|
||||||
The result will contain that directory (and only that) as its
|
The result will contain that directory (and only that) as its
|
||||||
project root.
|
project root. Implies --remap-to-ancestor.
|
||||||
|
|
||||||
|
--remap-to-ancestor::
|
||||||
|
Rewrite refs to the nearest rewritten ancestor instead of
|
||||||
|
ignoring them.
|
||||||
|
+
|
||||||
|
Normally, positive refs on the command line are only changed if the
|
||||||
|
commit they point to was rewritten. However, you can limit the extent
|
||||||
|
of this rewriting by using linkgit:rev-list[1] arguments, e.g., path
|
||||||
|
limiters. Refs pointing to such excluded commits would then normally
|
||||||
|
be ignored. With this option, they are instead rewritten to point at
|
||||||
|
the nearest ancestor that was not excluded.
|
||||||
|
|
||||||
--prune-empty::
|
--prune-empty::
|
||||||
Some kind of filters will generate empty commits, that left the tree
|
Some kind of filters will generate empty commits, that left the tree
|
||||||
|
@ -43,28 +43,28 @@ There are two ways to specify which commits to operate on.
|
|||||||
|
|
||||||
The first rule takes precedence in the case of a single <commit>. To
|
The first rule takes precedence in the case of a single <commit>. To
|
||||||
apply the second rule, i.e., format everything since the beginning of
|
apply the second rule, i.e., format everything since the beginning of
|
||||||
history up until <commit>, use the '\--root' option: "git format-patch
|
history up until <commit>, use the '\--root' option: `git format-patch
|
||||||
\--root <commit>". If you want to format only <commit> itself, you
|
\--root <commit>`. If you want to format only <commit> itself, you
|
||||||
can do this with "git format-patch -1 <commit>".
|
can do this with `git format-patch -1 <commit>`.
|
||||||
|
|
||||||
By default, each output file is numbered sequentially from 1, and uses the
|
By default, each output file is numbered sequentially from 1, and uses the
|
||||||
first line of the commit message (massaged for pathname safety) as
|
first line of the commit message (massaged for pathname safety) as
|
||||||
the filename. With the --numbered-files option, the output file names
|
the filename. With the `--numbered-files` option, the output file names
|
||||||
will only be numbers, without the first line of the commit appended.
|
will only be numbers, without the first line of the commit appended.
|
||||||
The names of the output files are printed to standard
|
The names of the output files are printed to standard
|
||||||
output, unless the --stdout option is specified.
|
output, unless the `--stdout` option is specified.
|
||||||
|
|
||||||
If -o is specified, output files are created in <dir>. Otherwise
|
If `-o` is specified, output files are created in <dir>. Otherwise
|
||||||
they are created in the current working directory.
|
they are created in the current working directory.
|
||||||
|
|
||||||
By default, the subject of a single patch is "[PATCH] First Line" and
|
By default, the subject of a single patch is "[PATCH] First Line" and
|
||||||
the subject when multiple patches are output is "[PATCH n/m] First
|
the subject when multiple patches are output is "[PATCH n/m] First
|
||||||
Line". To force 1/1 to be added for a single patch, use -n. To omit
|
Line". To force 1/1 to be added for a single patch, use `-n`. To omit
|
||||||
patch numbers from the subject, use -N
|
patch numbers from the subject, use `-N`.
|
||||||
|
|
||||||
If given --thread, 'git-format-patch' will generate In-Reply-To and
|
If given `--thread`, `git-format-patch` will generate `In-Reply-To` and
|
||||||
References headers to make the second and subsequent patch mails appear
|
`References` headers to make the second and subsequent patch mails appear
|
||||||
as replies to the first mail; this also generates a Message-Id header to
|
as replies to the first mail; this also generates a `Message-Id` header to
|
||||||
reference.
|
reference.
|
||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
@ -112,7 +112,7 @@ include::diff-options.txt[]
|
|||||||
--attach[=<boundary>]::
|
--attach[=<boundary>]::
|
||||||
Create multipart/mixed attachment, the first part of
|
Create multipart/mixed attachment, the first part of
|
||||||
which is the commit message and the patch itself in the
|
which is the commit message and the patch itself in the
|
||||||
second part, with "Content-Disposition: attachment".
|
second part, with `Content-Disposition: attachment`.
|
||||||
|
|
||||||
--no-attach::
|
--no-attach::
|
||||||
Disable the creation of an attachment, overriding the
|
Disable the creation of an attachment, overriding the
|
||||||
@ -121,13 +121,13 @@ include::diff-options.txt[]
|
|||||||
--inline[=<boundary>]::
|
--inline[=<boundary>]::
|
||||||
Create multipart/mixed attachment, the first part of
|
Create multipart/mixed attachment, the first part of
|
||||||
which is the commit message and the patch itself in the
|
which is the commit message and the patch itself in the
|
||||||
second part, with "Content-Disposition: inline".
|
second part, with `Content-Disposition: inline`.
|
||||||
|
|
||||||
--thread[=<style>]::
|
--thread[=<style>]::
|
||||||
--no-thread::
|
--no-thread::
|
||||||
Controls addition of In-Reply-To and References headers to
|
Controls addition of `In-Reply-To` and `References` headers to
|
||||||
make the second and subsequent mails appear as replies to the
|
make the second and subsequent mails appear as replies to the
|
||||||
first. Also controls generation of the Message-Id header to
|
first. Also controls generation of the `Message-Id` header to
|
||||||
reference.
|
reference.
|
||||||
+
|
+
|
||||||
The optional <style> argument can be either `shallow` or `deep`.
|
The optional <style> argument can be either `shallow` or `deep`.
|
||||||
@ -136,16 +136,16 @@ series, where the head is chosen from the cover letter, the
|
|||||||
`\--in-reply-to`, and the first patch mail, in this order. 'deep'
|
`\--in-reply-to`, and the first patch mail, in this order. 'deep'
|
||||||
threading makes every mail a reply to the previous one.
|
threading makes every mail a reply to the previous one.
|
||||||
+
|
+
|
||||||
The default is --no-thread, unless the 'format.thread' configuration
|
The default is `--no-thread`, unless the 'format.thread' configuration
|
||||||
is set. If --thread is specified without a style, it defaults to the
|
is set. If `--thread` is specified without a style, it defaults to the
|
||||||
style specified by 'format.thread' if any, or else `shallow`.
|
style specified by 'format.thread' if any, or else `shallow`.
|
||||||
+
|
+
|
||||||
Beware that the default for 'git send-email' is to thread emails
|
Beware that the default for 'git send-email' is to thread emails
|
||||||
itself. If you want 'git format-patch' to take care of hreading, you
|
itself. If you want `git format-patch` to take care of threading, you
|
||||||
will want to ensure that threading is disabled for 'git send-email'.
|
will want to ensure that threading is disabled for `git send-email`.
|
||||||
|
|
||||||
--in-reply-to=Message-Id::
|
--in-reply-to=Message-Id::
|
||||||
Make the first mail (or all the mails with --no-thread) appear as a
|
Make the first mail (or all the mails with `--no-thread`) appear as a
|
||||||
reply to the given Message-Id, which avoids breaking threads to
|
reply to the given Message-Id, which avoids breaking threads to
|
||||||
provide a new patch series.
|
provide a new patch series.
|
||||||
|
|
||||||
@ -160,16 +160,16 @@ will want to ensure that threading is disabled for 'git send-email'.
|
|||||||
Instead of the standard '[PATCH]' prefix in the subject
|
Instead of the standard '[PATCH]' prefix in the subject
|
||||||
line, instead use '[<Subject-Prefix>]'. This
|
line, instead use '[<Subject-Prefix>]'. This
|
||||||
allows for useful naming of a patch series, and can be
|
allows for useful naming of a patch series, and can be
|
||||||
combined with the --numbered option.
|
combined with the `--numbered` option.
|
||||||
|
|
||||||
--cc=<email>::
|
--cc=<email>::
|
||||||
Add a "Cc:" header to the email headers. This is in addition
|
Add a `Cc:` header to the email headers. This is in addition
|
||||||
to any configured headers, and may be used multiple times.
|
to any configured headers, and may be used multiple times.
|
||||||
|
|
||||||
--add-header=<header>::
|
--add-header=<header>::
|
||||||
Add an arbitrary header to the email headers. This is in addition
|
Add an arbitrary header to the email headers. This is in addition
|
||||||
to any configured headers, and may be used multiple times.
|
to any configured headers, and may be used multiple times.
|
||||||
For example, --add-header="Organization: git-foo"
|
For example, `--add-header="Organization: git-foo"`
|
||||||
|
|
||||||
--cover-letter::
|
--cover-letter::
|
||||||
In addition to the patches, generate a cover letter file
|
In addition to the patches, generate a cover letter file
|
||||||
|
@ -10,7 +10,7 @@ SYNOPSIS
|
|||||||
--------
|
--------
|
||||||
[verse]
|
[verse]
|
||||||
'git fsck' [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]
|
'git fsck' [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]
|
||||||
[--full] [--strict] [--verbose] [--lost-found] [<object>*]
|
[--[no-]full] [--strict] [--verbose] [--lost-found] [<object>*]
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
@ -52,7 +52,8 @@ index file, all SHA1 references in .git/refs/*, and all reflogs (unless
|
|||||||
or $GIT_DIR/objects/info/alternates,
|
or $GIT_DIR/objects/info/alternates,
|
||||||
and in packed git archives found in $GIT_DIR/objects/pack
|
and in packed git archives found in $GIT_DIR/objects/pack
|
||||||
and corresponding pack subdirectories in alternate
|
and corresponding pack subdirectories in alternate
|
||||||
object pools.
|
object pools. This is now default; you can turn it off
|
||||||
|
with --no-full.
|
||||||
|
|
||||||
--strict::
|
--strict::
|
||||||
Enable more strict checking, namely to catch a file mode
|
Enable more strict checking, namely to catch a file mode
|
||||||
|
@ -120,7 +120,7 @@ Notes
|
|||||||
particular, it will keep not only objects referenced by your current set
|
particular, it will keep not only objects referenced by your current set
|
||||||
of branches and tags, but also objects referenced by the index, remote
|
of branches and tags, but also objects referenced by the index, remote
|
||||||
tracking branches, refs saved by 'git-filter-branch' in
|
tracking branches, refs saved by 'git-filter-branch' in
|
||||||
refs/original/, or reflogs (which may references commits in branches
|
refs/original/, or reflogs (which may reference commits in branches
|
||||||
that were later amended or rewound).
|
that were later amended or rewound).
|
||||||
|
|
||||||
If you are expecting some objects to be collected and they aren't, check
|
If you are expecting some objects to be collected and they aren't, check
|
||||||
|
178
Documentation/git-http-backend.txt
Normal file
178
Documentation/git-http-backend.txt
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
git-http-backend(1)
|
||||||
|
===================
|
||||||
|
|
||||||
|
NAME
|
||||||
|
----
|
||||||
|
git-http-backend - Server side implementation of Git over HTTP
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
--------
|
||||||
|
[verse]
|
||||||
|
'git-http-backend'
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
-----------
|
||||||
|
A simple CGI program to serve the contents of a Git repository to Git
|
||||||
|
clients accessing the repository over http:// and https:// protocols.
|
||||||
|
The program supports clients fetching using both the smart HTTP protcol
|
||||||
|
and the backwards-compatible dumb HTTP protocol, as well as clients
|
||||||
|
pushing using the smart HTTP protocol.
|
||||||
|
|
||||||
|
By default, only the `upload-pack` service is enabled, which serves
|
||||||
|
'git-fetch-pack' and 'git-ls-remote' clients, which are invoked from
|
||||||
|
'git-fetch', 'git-pull', and 'git-clone'. If the client is authenticated,
|
||||||
|
the `receive-pack` service is enabled, which serves 'git-send-pack'
|
||||||
|
clients, which is invoked from 'git-push'.
|
||||||
|
|
||||||
|
SERVICES
|
||||||
|
--------
|
||||||
|
These services can be enabled/disabled using the per-repository
|
||||||
|
configuration file:
|
||||||
|
|
||||||
|
http.getanyfile::
|
||||||
|
This serves older Git clients which are unable to use the
|
||||||
|
upload pack service. When enabled, clients are able to read
|
||||||
|
any file within the repository, including objects that are
|
||||||
|
no longer reachable from a branch but are still present.
|
||||||
|
It is enabled by default, but a repository can disable it
|
||||||
|
by setting this configuration item to `false`.
|
||||||
|
|
||||||
|
http.uploadpack::
|
||||||
|
This serves 'git-fetch-pack' and 'git-ls-remote' clients.
|
||||||
|
It is enabled by default, but a repository can disable it
|
||||||
|
by setting this configuration item to `false`.
|
||||||
|
|
||||||
|
http.receivepack::
|
||||||
|
This serves 'git-send-pack' clients, allowing push. It is
|
||||||
|
disabled by default for anonymous users, and enabled by
|
||||||
|
default for users authenticated by the web server. It can be
|
||||||
|
disabled by setting this item to `false`, or enabled for all
|
||||||
|
users, including anonymous users, by setting it to `true`.
|
||||||
|
|
||||||
|
URL TRANSLATION
|
||||||
|
---------------
|
||||||
|
To determine the location of the repository on disk, 'git-http-backend'
|
||||||
|
concatenates the environment variables PATH_INFO, which is set
|
||||||
|
automatically by the web server, and GIT_PROJECT_ROOT, which must be set
|
||||||
|
manually in the web server configuration. If GIT_PROJECT_ROOT is not
|
||||||
|
set, 'git-http-backend' reads PATH_TRANSLATED, which is also set
|
||||||
|
automatically by the web server.
|
||||||
|
|
||||||
|
EXAMPLES
|
||||||
|
--------
|
||||||
|
All of the following examples map 'http://$hostname/git/foo/bar.git'
|
||||||
|
to '/var/www/git/foo/bar.git'.
|
||||||
|
|
||||||
|
Apache 2.x::
|
||||||
|
Ensure mod_cgi, mod_alias, and mod_env are enabled, set
|
||||||
|
GIT_PROJECT_ROOT (or DocumentRoot) appropriately, and
|
||||||
|
create a ScriptAlias to the CGI:
|
||||||
|
+
|
||||||
|
----------------------------------------------------------------
|
||||||
|
SetEnv GIT_PROJECT_ROOT /var/www/git
|
||||||
|
ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
|
||||||
|
----------------------------------------------------------------
|
||||||
|
+
|
||||||
|
To enable anonymous read access but authenticated write access,
|
||||||
|
require authorization with a LocationMatch directive:
|
||||||
|
+
|
||||||
|
----------------------------------------------------------------
|
||||||
|
<LocationMatch "^/git/.*/git-receive-pack$">
|
||||||
|
AuthType Basic
|
||||||
|
AuthName "Git Access"
|
||||||
|
Require group committers
|
||||||
|
...
|
||||||
|
</LocationMatch>
|
||||||
|
----------------------------------------------------------------
|
||||||
|
+
|
||||||
|
To require authentication for both reads and writes, use a Location
|
||||||
|
directive around the repository, or one of its parent directories:
|
||||||
|
+
|
||||||
|
----------------------------------------------------------------
|
||||||
|
<Location /git/private>
|
||||||
|
AuthType Basic
|
||||||
|
AuthName "Private Git Access"
|
||||||
|
Require group committers
|
||||||
|
...
|
||||||
|
</Location>
|
||||||
|
----------------------------------------------------------------
|
||||||
|
+
|
||||||
|
To serve gitweb at the same url, use a ScriptAliasMatch to only
|
||||||
|
those URLs that 'git-http-backend' can handle, and forward the
|
||||||
|
rest to gitweb:
|
||||||
|
+
|
||||||
|
----------------------------------------------------------------
|
||||||
|
ScriptAliasMatch \
|
||||||
|
"(?x)^/git/(.*/(HEAD | \
|
||||||
|
info/refs | \
|
||||||
|
objects/(info/[^/]+ | \
|
||||||
|
[0-9a-f]{2}/[0-9a-f]{38} | \
|
||||||
|
pack/pack-[0-9a-f]{40}\.(pack|idx)) | \
|
||||||
|
git-(upload|receive)-pack))$" \
|
||||||
|
/usr/libexec/git-core/git-http-backend/$1
|
||||||
|
|
||||||
|
ScriptAlias /git/ /var/www/cgi-bin/gitweb.cgi/
|
||||||
|
----------------------------------------------------------------
|
||||||
|
|
||||||
|
Accelerated static Apache 2.x::
|
||||||
|
Similar to the above, but Apache can be used to return static
|
||||||
|
files that are stored on disk. On many systems this may
|
||||||
|
be more efficient as Apache can ask the kernel to copy the
|
||||||
|
file contents from the file system directly to the network:
|
||||||
|
+
|
||||||
|
----------------------------------------------------------------
|
||||||
|
SetEnv GIT_PROJECT_ROOT /var/www/git
|
||||||
|
|
||||||
|
AliasMatch ^/git/(.*/objects/[0-9a-f]{2}/[0-9a-f]{38})$ /var/www/git/$1
|
||||||
|
AliasMatch ^/git/(.*/objects/pack/pack-[0-9a-f]{40}.(pack|idx))$ /var/www/git/$1
|
||||||
|
ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
|
||||||
|
----------------------------------------------------------------
|
||||||
|
+
|
||||||
|
This can be combined with the gitweb configuration:
|
||||||
|
+
|
||||||
|
----------------------------------------------------------------
|
||||||
|
SetEnv GIT_PROJECT_ROOT /var/www/git
|
||||||
|
|
||||||
|
AliasMatch ^/git/(.*/objects/[0-9a-f]{2}/[0-9a-f]{38})$ /var/www/git/$1
|
||||||
|
AliasMatch ^/git/(.*/objects/pack/pack-[0-9a-f]{40}.(pack|idx))$ /var/www/git/$1
|
||||||
|
ScriptAliasMatch \
|
||||||
|
"(?x)^/git/(.*/(HEAD | \
|
||||||
|
info/refs | \
|
||||||
|
objects/info/[^/]+ | \
|
||||||
|
git-(upload|receive)-pack))$" \
|
||||||
|
/usr/libexec/git-core/git-http-backend/$1
|
||||||
|
ScriptAlias /git/ /var/www/cgi-bin/gitweb.cgi/
|
||||||
|
----------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
ENVIRONMENT
|
||||||
|
-----------
|
||||||
|
'git-http-backend' relies upon the CGI environment variables set
|
||||||
|
by the invoking web server, including:
|
||||||
|
|
||||||
|
* PATH_INFO (if GIT_PROJECT_ROOT is set, otherwise PATH_TRANSLATED)
|
||||||
|
* REMOTE_USER
|
||||||
|
* REMOTE_ADDR
|
||||||
|
* CONTENT_TYPE
|
||||||
|
* QUERY_STRING
|
||||||
|
* REQUEST_METHOD
|
||||||
|
|
||||||
|
The backend process sets GIT_COMMITTER_NAME to '$REMOTE_USER' and
|
||||||
|
GIT_COMMITTER_EMAIL to '$\{REMOTE_USER}@http.$\{REMOTE_ADDR\}',
|
||||||
|
ensuring that any reflogs created by 'git-receive-pack' contain some
|
||||||
|
identifying information of the remote user who performed the push.
|
||||||
|
|
||||||
|
All CGI environment variables are available to each of the hooks
|
||||||
|
invoked by the 'git-receive-pack'.
|
||||||
|
|
||||||
|
Author
|
||||||
|
------
|
||||||
|
Written by Shawn O. Pearce <spearce@spearce.org>.
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
--------------
|
||||||
|
Documentation by Shawn O. Pearce <spearce@spearce.org>.
|
||||||
|
|
||||||
|
GIT
|
||||||
|
---
|
||||||
|
Part of the linkgit:git[1] suite
|
@ -82,11 +82,11 @@ destination side.
|
|||||||
|
|
||||||
Without '--force', the <src> ref is stored at the remote only if
|
Without '--force', the <src> ref is stored at the remote only if
|
||||||
<dst> does not exist, or <dst> is a proper subset (i.e. an
|
<dst> does not exist, or <dst> is a proper subset (i.e. an
|
||||||
ancestor) of <src>. This check, known as "fast forward check",
|
ancestor) of <src>. This check, known as "fast-forward check",
|
||||||
is performed in order to avoid accidentally overwriting the
|
is performed in order to avoid accidentally overwriting the
|
||||||
remote ref and lose other peoples' commits from there.
|
remote ref and lose other peoples' commits from there.
|
||||||
|
|
||||||
With '--force', the fast forward check is disabled for all refs.
|
With '--force', the fast-forward check is disabled for all refs.
|
||||||
|
|
||||||
Optionally, a <ref> parameter can be prefixed with a plus '+' sign
|
Optionally, a <ref> parameter can be prefixed with a plus '+' sign
|
||||||
to disable the fast-forward check only on that ref.
|
to disable the fast-forward check only on that ref.
|
||||||
|
@ -48,8 +48,10 @@ OPTIONS
|
|||||||
|
|
||||||
-i::
|
-i::
|
||||||
--ignored::
|
--ignored::
|
||||||
Show ignored files in the output.
|
Show only ignored files in the output. When showing files in the
|
||||||
Note that this also reverses any exclude list present.
|
index, print only those matched by an exclude pattern. When
|
||||||
|
showing "other" files, show only those matched by an exclude
|
||||||
|
pattern.
|
||||||
|
|
||||||
-s::
|
-s::
|
||||||
--stage::
|
--stage::
|
||||||
|
@ -212,6 +212,39 @@ You can work through the conflict with a number of tools:
|
|||||||
common ancestor, 'git show :2:filename' shows the HEAD
|
common ancestor, 'git show :2:filename' shows the HEAD
|
||||||
version and 'git show :3:filename' shows the remote version.
|
version and 'git show :3:filename' shows the remote version.
|
||||||
|
|
||||||
|
|
||||||
|
EXAMPLES
|
||||||
|
--------
|
||||||
|
|
||||||
|
* Merge branches `fixes` and `enhancements` on top of
|
||||||
|
the current branch, making an octopus merge:
|
||||||
|
+
|
||||||
|
------------------------------------------------
|
||||||
|
$ git merge fixes enhancements
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
* Merge branch `obsolete` into the current branch, using `ours`
|
||||||
|
merge strategy:
|
||||||
|
+
|
||||||
|
------------------------------------------------
|
||||||
|
$ git merge -s ours obsolete
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
* Merge branch `maint` into the current branch, but do not make
|
||||||
|
a new commit automatically:
|
||||||
|
+
|
||||||
|
------------------------------------------------
|
||||||
|
$ git merge --no-commit maint
|
||||||
|
------------------------------------------------
|
||||||
|
+
|
||||||
|
This can be used when you want to include further changes to the
|
||||||
|
merge, or want to write your own merge commit message.
|
||||||
|
+
|
||||||
|
You should refrain from abusing this option to sneak substantial
|
||||||
|
changes into a merge commit. Small fixups like bumping
|
||||||
|
release/version name would be acceptable.
|
||||||
|
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
--------
|
--------
|
||||||
linkgit:git-fmt-merge-msg[1], linkgit:git-pull[1],
|
linkgit:git-fmt-merge-msg[1], linkgit:git-pull[1],
|
||||||
|
@ -27,7 +27,7 @@ OPTIONS
|
|||||||
Use the merge resolution program specified by <tool>.
|
Use the merge resolution program specified by <tool>.
|
||||||
Valid merge tools are:
|
Valid merge tools are:
|
||||||
kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge,
|
kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge,
|
||||||
diffuse, tortoisemerge, opendiff and araxis.
|
diffuse, tortoisemerge, opendiff, p4merge and araxis.
|
||||||
+
|
+
|
||||||
If a merge resolution program is not specified, 'git-mergetool'
|
If a merge resolution program is not specified, 'git-mergetool'
|
||||||
will use the configuration variable `merge.tool`. If the
|
will use the configuration variable `merge.tool`. If the
|
||||||
|
60
Documentation/git-notes.txt
Normal file
60
Documentation/git-notes.txt
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
git-notes(1)
|
||||||
|
============
|
||||||
|
|
||||||
|
NAME
|
||||||
|
----
|
||||||
|
git-notes - Add/inspect commit notes
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
--------
|
||||||
|
[verse]
|
||||||
|
'git-notes' (edit [-F <file> | -m <msg>] | show) [commit]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
-----------
|
||||||
|
This command allows you to add notes to commit messages, without
|
||||||
|
changing the commit. To discern these notes from the message stored
|
||||||
|
in the commit object, the notes are indented like the message, after
|
||||||
|
an unindented line saying "Notes:".
|
||||||
|
|
||||||
|
To disable commit notes, you have to set the config variable
|
||||||
|
core.notesRef to the empty string. Alternatively, you can set it
|
||||||
|
to a different ref, something like "refs/notes/bugzilla". This setting
|
||||||
|
can be overridden by the environment variable "GIT_NOTES_REF".
|
||||||
|
|
||||||
|
|
||||||
|
SUBCOMMANDS
|
||||||
|
-----------
|
||||||
|
|
||||||
|
edit::
|
||||||
|
Edit the notes for a given commit (defaults to HEAD).
|
||||||
|
|
||||||
|
show::
|
||||||
|
Show the notes for a given commit (defaults to HEAD).
|
||||||
|
|
||||||
|
|
||||||
|
OPTIONS
|
||||||
|
-------
|
||||||
|
-m <msg>::
|
||||||
|
Use the given note message (instead of prompting).
|
||||||
|
If multiple `-m` (or `-F`) options are given, their
|
||||||
|
values are concatenated as separate paragraphs.
|
||||||
|
|
||||||
|
-F <file>::
|
||||||
|
Take the note message from the given file. Use '-' to
|
||||||
|
read the note message from the standard input.
|
||||||
|
If multiple `-F` (or `-m`) options are given, their
|
||||||
|
values are concatenated as separate paragraphs.
|
||||||
|
|
||||||
|
|
||||||
|
Author
|
||||||
|
------
|
||||||
|
Written by Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
-------------
|
||||||
|
Documentation by Johannes Schindelin
|
||||||
|
|
||||||
|
GIT
|
||||||
|
---
|
||||||
|
Part of the linkgit:git[7] suite
|
@ -9,8 +9,9 @@ git-pack-objects - Create a packed archive of objects
|
|||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
[verse]
|
[verse]
|
||||||
'git pack-objects' [-q] [--no-reuse-delta] [--delta-base-offset] [--non-empty]
|
'git pack-objects' [-q | --progress | --all-progress] [--all-progress-implied]
|
||||||
[--local] [--incremental] [--window=N] [--depth=N] [--all-progress]
|
[--no-reuse-delta] [--delta-base-offset] [--non-empty]
|
||||||
|
[--local] [--incremental] [--window=N] [--depth=N]
|
||||||
[--revs [--unpacked | --all]*] [--stdout | base-name]
|
[--revs [--unpacked | --all]*] [--stdout | base-name]
|
||||||
[--keep-true-parents] < object-list
|
[--keep-true-parents] < object-list
|
||||||
|
|
||||||
@ -137,7 +138,7 @@ base-name::
|
|||||||
|
|
||||||
--all-progress::
|
--all-progress::
|
||||||
When --stdout is specified then progress report is
|
When --stdout is specified then progress report is
|
||||||
displayed during the object count and deltification phases
|
displayed during the object count and compression phases
|
||||||
but inhibited during the write-out phase. The reason is
|
but inhibited during the write-out phase. The reason is
|
||||||
that in some cases the output stream is directly linked
|
that in some cases the output stream is directly linked
|
||||||
to another command which may wish to display progress
|
to another command which may wish to display progress
|
||||||
@ -146,6 +147,11 @@ base-name::
|
|||||||
report for the write-out phase as well even if --stdout is
|
report for the write-out phase as well even if --stdout is
|
||||||
used.
|
used.
|
||||||
|
|
||||||
|
--all-progress-implied::
|
||||||
|
This is used to imply --all-progress whenever progress display
|
||||||
|
is activated. Unlike --all-progress this flag doesn't actually
|
||||||
|
force any progress display by itself.
|
||||||
|
|
||||||
-q::
|
-q::
|
||||||
This flag makes the command not to report its progress
|
This flag makes the command not to report its progress
|
||||||
on the standard error stream.
|
on the standard error stream.
|
||||||
|
@ -26,6 +26,10 @@ Also note that options meant for 'git-pull' itself and underlying
|
|||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
Options related to merging
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
include::merge-options.txt[]
|
include::merge-options.txt[]
|
||||||
|
|
||||||
:git-pull: 1
|
:git-pull: 1
|
||||||
@ -47,6 +51,9 @@ unless you have read linkgit:git-rebase[1] carefully.
|
|||||||
--no-rebase::
|
--no-rebase::
|
||||||
Override earlier --rebase.
|
Override earlier --rebase.
|
||||||
|
|
||||||
|
Options related to fetching
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
include::fetch-options.txt[]
|
include::fetch-options.txt[]
|
||||||
|
|
||||||
include::pull-fetch-param.txt[]
|
include::pull-fetch-param.txt[]
|
||||||
@ -131,54 +138,13 @@ $ git pull origin next
|
|||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
+
|
+
|
||||||
This leaves a copy of `next` temporarily in FETCH_HEAD, but
|
This leaves a copy of `next` temporarily in FETCH_HEAD, but
|
||||||
does not update any remote-tracking branches.
|
does not update any remote-tracking branches. Using remote-tracking
|
||||||
|
branches, the same can be done by invoking fetch and merge:
|
||||||
* Bundle local branch `fixes` and `enhancements` on top of
|
|
||||||
the current branch, making an Octopus merge:
|
|
||||||
+
|
+
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
$ git pull . fixes enhancements
|
$ git fetch origin
|
||||||
|
$ git merge origin/next
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
+
|
|
||||||
This `git pull .` syntax is equivalent to `git merge`.
|
|
||||||
|
|
||||||
* Merge local branch `obsolete` into the current branch, using `ours`
|
|
||||||
merge strategy:
|
|
||||||
+
|
|
||||||
------------------------------------------------
|
|
||||||
$ git pull -s ours . obsolete
|
|
||||||
------------------------------------------------
|
|
||||||
|
|
||||||
* Merge local branch `maint` into the current branch, but do not make
|
|
||||||
a commit automatically:
|
|
||||||
+
|
|
||||||
------------------------------------------------
|
|
||||||
$ git pull --no-commit . maint
|
|
||||||
------------------------------------------------
|
|
||||||
+
|
|
||||||
This can be used when you want to include further changes to the
|
|
||||||
merge, or want to write your own merge commit message.
|
|
||||||
+
|
|
||||||
You should refrain from abusing this option to sneak substantial
|
|
||||||
changes into a merge commit. Small fixups like bumping
|
|
||||||
release/version name would be acceptable.
|
|
||||||
|
|
||||||
* Command line pull of multiple branches from one repository:
|
|
||||||
+
|
|
||||||
------------------------------------------------
|
|
||||||
$ git checkout master
|
|
||||||
$ git fetch origin +pu:pu maint:tmp
|
|
||||||
$ git pull . tmp
|
|
||||||
------------------------------------------------
|
|
||||||
+
|
|
||||||
This updates (or creates, as necessary) branches `pu` and `tmp` in
|
|
||||||
the local repository by fetching from the branches (respectively)
|
|
||||||
`pu` and `maint` from the remote repository.
|
|
||||||
+
|
|
||||||
The `pu` branch will be updated even if it is does not fast-forward;
|
|
||||||
the others will not be.
|
|
||||||
+
|
|
||||||
The final command then merges the newly fetched `tmp` into master.
|
|
||||||
|
|
||||||
|
|
||||||
If you tried a pull which resulted in a complex conflicts and
|
If you tried a pull which resulted in a complex conflicts and
|
||||||
|
@ -50,9 +50,9 @@ updated.
|
|||||||
+
|
+
|
||||||
The object referenced by <src> is used to update the <dst> reference
|
The object referenced by <src> is used to update the <dst> reference
|
||||||
on the remote side, but by default this is only allowed if the
|
on the remote side, but by default this is only allowed if the
|
||||||
update can fast forward <dst>. By having the optional leading `{plus}`,
|
update can fast-forward <dst>. By having the optional leading `{plus}`,
|
||||||
you can tell git to update the <dst> ref even when the update is not a
|
you can tell git to update the <dst> ref even when the update is not a
|
||||||
fast forward. This does *not* attempt to merge <src> into <dst>. See
|
fast-forward. This does *not* attempt to merge <src> into <dst>. See
|
||||||
EXAMPLES below for details.
|
EXAMPLES below for details.
|
||||||
+
|
+
|
||||||
`tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`.
|
`tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`.
|
||||||
@ -60,7 +60,7 @@ EXAMPLES below for details.
|
|||||||
Pushing an empty <src> allows you to delete the <dst> ref from
|
Pushing an empty <src> allows you to delete the <dst> ref from
|
||||||
the remote repository.
|
the remote repository.
|
||||||
+
|
+
|
||||||
The special refspec `:` (or `{plus}:` to allow non-fast forward updates)
|
The special refspec `:` (or `{plus}:` to allow non-fast-forward updates)
|
||||||
directs git to push "matching" branches: for every branch that exists on
|
directs git to push "matching" branches: for every branch that exists on
|
||||||
the local side, the remote side is updated if a branch of the same name
|
the local side, the remote side is updated if a branch of the same name
|
||||||
already exists on the remote side. This is the default operation mode
|
already exists on the remote side. This is the default operation mode
|
||||||
@ -138,6 +138,11 @@ useful if you write an alias or script around 'git-push'.
|
|||||||
--verbose::
|
--verbose::
|
||||||
Run verbosely.
|
Run verbosely.
|
||||||
|
|
||||||
|
-q::
|
||||||
|
--quiet::
|
||||||
|
Suppress all output, including the listing of updated refs,
|
||||||
|
unless an error occurs.
|
||||||
|
|
||||||
include::urls-remotes.txt[]
|
include::urls-remotes.txt[]
|
||||||
|
|
||||||
OUTPUT
|
OUTPUT
|
||||||
@ -171,10 +176,10 @@ summary::
|
|||||||
For a successfully pushed ref, the summary shows the old and new
|
For a successfully pushed ref, the summary shows the old and new
|
||||||
values of the ref in a form suitable for using as an argument to
|
values of the ref in a form suitable for using as an argument to
|
||||||
`git log` (this is `<old>..<new>` in most cases, and
|
`git log` (this is `<old>..<new>` in most cases, and
|
||||||
`<old>...<new>` for forced non-fast forward updates). For a
|
`<old>...<new>` for forced non-fast-forward updates). For a
|
||||||
failed update, more details are given for the failure.
|
failed update, more details are given for the failure.
|
||||||
The string `rejected` indicates that git did not try to send the
|
The string `rejected` indicates that git did not try to send the
|
||||||
ref at all (typically because it is not a fast forward). The
|
ref at all (typically because it is not a fast-forward). The
|
||||||
string `remote rejected` indicates that the remote end refused
|
string `remote rejected` indicates that the remote end refused
|
||||||
the update; this rejection is typically caused by a hook on the
|
the update; this rejection is typically caused by a hook on the
|
||||||
remote side. The string `remote failure` indicates that the
|
remote side. The string `remote failure` indicates that the
|
||||||
@ -342,9 +347,9 @@ git push origin :experimental::
|
|||||||
|
|
||||||
git push origin {plus}dev:master::
|
git push origin {plus}dev:master::
|
||||||
Update the origin repository's master branch with the dev branch,
|
Update the origin repository's master branch with the dev branch,
|
||||||
allowing non-fast forward updates. *This can leave unreferenced
|
allowing non-fast-forward updates. *This can leave unreferenced
|
||||||
commits dangling in the origin repository.* Consider the
|
commits dangling in the origin repository.* Consider the
|
||||||
following situation, where a fast forward is not possible:
|
following situation, where a fast-forward is not possible:
|
||||||
+
|
+
|
||||||
----
|
----
|
||||||
o---o---o---A---B origin/master
|
o---o---o---A---B origin/master
|
||||||
|
@ -144,7 +144,7 @@ Two Tree Merge
|
|||||||
Typically, this is invoked as `git read-tree -m $H $M`, where $H
|
Typically, this is invoked as `git read-tree -m $H $M`, where $H
|
||||||
is the head commit of the current repository, and $M is the head
|
is the head commit of the current repository, and $M is the head
|
||||||
of a foreign tree, which is simply ahead of $H (i.e. we are in a
|
of a foreign tree, which is simply ahead of $H (i.e. we are in a
|
||||||
fast forward situation).
|
fast-forward situation).
|
||||||
|
|
||||||
When two trees are specified, the user is telling 'git-read-tree'
|
When two trees are specified, the user is telling 'git-read-tree'
|
||||||
the following:
|
the following:
|
||||||
|
@ -228,13 +228,23 @@ OPTIONS
|
|||||||
Use merging strategies to rebase. When the recursive (default) merge
|
Use merging strategies to rebase. When the recursive (default) merge
|
||||||
strategy is used, this allows rebase to be aware of renames on the
|
strategy is used, this allows rebase to be aware of renames on the
|
||||||
upstream side.
|
upstream side.
|
||||||
|
+
|
||||||
|
Note that a rebase merge works by replaying each commit from the working
|
||||||
|
branch on top of the <upstream> branch. Because of this, when a merge
|
||||||
|
conflict happens, the side reported as 'ours' is the so-far rebased
|
||||||
|
series, starting with <upstream>, and 'theirs' is the working branch. In
|
||||||
|
other words, the sides are swapped.
|
||||||
|
|
||||||
-s <strategy>::
|
-s <strategy>::
|
||||||
--strategy=<strategy>::
|
--strategy=<strategy>::
|
||||||
Use the given merge strategy.
|
Use the given merge strategy.
|
||||||
If there is no `-s` option, a built-in list of strategies
|
If there is no `-s` option 'git-merge-recursive' is used
|
||||||
is used instead ('git-merge-recursive' when merging a single
|
instead. This implies --merge.
|
||||||
head, 'git-merge-octopus' otherwise). This implies --merge.
|
+
|
||||||
|
Because 'git-rebase' replays each commit from the working branch
|
||||||
|
on top of the <upstream> branch using the given strategy, using
|
||||||
|
the 'ours' strategy simply discards all patches from the <branch>,
|
||||||
|
which makes little sense.
|
||||||
|
|
||||||
-q::
|
-q::
|
||||||
--quiet::
|
--quiet::
|
||||||
@ -368,14 +378,17 @@ By replacing the command "pick" with the command "edit", you can tell
|
|||||||
the files and/or the commit message, amend the commit, and continue
|
the files and/or the commit message, amend the commit, and continue
|
||||||
rebasing.
|
rebasing.
|
||||||
|
|
||||||
|
If you just want to edit the commit message for a commit, replace the
|
||||||
|
command "pick" with the command "reword".
|
||||||
|
|
||||||
If you want to fold two or more commits into one, replace the command
|
If you want to fold two or more commits into one, replace the command
|
||||||
"pick" with "squash" for the second and subsequent commit. If the
|
"pick" with "squash" for the second and subsequent commit. If the
|
||||||
commits had different authors, it will attribute the squashed commit to
|
commits had different authors, it will attribute the squashed commit to
|
||||||
the author of the first commit.
|
the author of the first commit.
|
||||||
|
|
||||||
In both cases, or when a "pick" does not succeed (because of merge
|
'git-rebase' will stop when "pick" has been replaced with "edit" or
|
||||||
errors), the loop will stop to let you fix things, and you can continue
|
when a command fails due to merge errors. When you are done editing
|
||||||
the loop with `git rebase --continue`.
|
and/or resolving conflicts you can continue with `git rebase --continue`.
|
||||||
|
|
||||||
For example, if you want to reorder the last 5 commits, such that what
|
For example, if you want to reorder the last 5 commits, such that what
|
||||||
was HEAD~4 becomes the new HEAD. To achieve that, you would call
|
was HEAD~4 becomes the new HEAD. To achieve that, you would call
|
||||||
|
@ -20,7 +20,7 @@ The UI for the protocol is on the 'git-send-pack' side, and the
|
|||||||
program pair is meant to be used to push updates to remote
|
program pair is meant to be used to push updates to remote
|
||||||
repository. For pull operations, see linkgit:git-fetch-pack[1].
|
repository. For pull operations, see linkgit:git-fetch-pack[1].
|
||||||
|
|
||||||
The command allows for creation and fast forwarding of sha1 refs
|
The command allows for creation and fast-forwarding of sha1 refs
|
||||||
(heads/tags) on the remote end (strictly speaking, it is the
|
(heads/tags) on the remote end (strictly speaking, it is the
|
||||||
local end 'git-receive-pack' runs, but to the user who is sitting at
|
local end 'git-receive-pack' runs, but to the user who is sitting at
|
||||||
the send-pack end, it is updating the remote. Confused?)
|
the send-pack end, it is updating the remote. Confused?)
|
||||||
|
@ -34,15 +34,51 @@ Commands are given by the caller on the helper's standard input, one per line.
|
|||||||
value of the ref. A space-separated list of attributes follows
|
value of the ref. A space-separated list of attributes follows
|
||||||
the name; unrecognized attributes are ignored. After the
|
the name; unrecognized attributes are ignored. After the
|
||||||
complete list, outputs a blank line.
|
complete list, outputs a blank line.
|
||||||
|
+
|
||||||
|
If 'push' is supported this may be called as 'list for-push'
|
||||||
|
to obtain the current refs prior to sending one or more 'push'
|
||||||
|
commands to the helper.
|
||||||
|
|
||||||
|
'option' <name> <value>::
|
||||||
|
Set the transport helper option <name> to <value>. Outputs a
|
||||||
|
single line containing one of 'ok' (option successfully set),
|
||||||
|
'unsupported' (option not recognized) or 'error <msg>'
|
||||||
|
(option <name> is supported but <value> is not correct
|
||||||
|
for it). Options should be set before other commands,
|
||||||
|
and may how those commands behave.
|
||||||
|
+
|
||||||
|
Supported if the helper has the "option" capability.
|
||||||
|
|
||||||
'fetch' <sha1> <name>::
|
'fetch' <sha1> <name>::
|
||||||
Fetches the given object, writing the necessary objects to the
|
Fetches the given object, writing the necessary objects
|
||||||
database. Outputs a blank line when the fetch is
|
to the database. Fetch commands are sent in a batch, one
|
||||||
complete. Only objects which were reported in the ref list
|
per line, and the batch is terminated with a blank line.
|
||||||
with a sha1 may be fetched this way.
|
Outputs a single blank line when all fetch commands in the
|
||||||
|
same batch are complete. Only objects which were reported
|
||||||
|
in the ref list with a sha1 may be fetched this way.
|
||||||
|
+
|
||||||
|
Optionally may output a 'lock <file>' line indicating a file under
|
||||||
|
GIT_DIR/objects/pack which is keeping a pack until refs can be
|
||||||
|
suitably updated.
|
||||||
+
|
+
|
||||||
Supported if the helper has the "fetch" capability.
|
Supported if the helper has the "fetch" capability.
|
||||||
|
|
||||||
|
'push' +<src>:<dst>::
|
||||||
|
Pushes the given <src> commit or branch locally to the
|
||||||
|
remote branch described by <dst>. A batch sequence of
|
||||||
|
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.
|
||||||
|
+
|
||||||
|
When the push is complete, outputs one or more 'ok <dst>' or
|
||||||
|
'error <dst> <why>?' lines to indicate success or failure of
|
||||||
|
each pushed ref. The status report output is terminated by
|
||||||
|
a blank line. The option field <why> may be quoted in a C
|
||||||
|
style string if it contains an LF.
|
||||||
|
+
|
||||||
|
Supported if the helper has the "push" capability.
|
||||||
|
|
||||||
If a fatal error occurs, the program writes the error message to
|
If a fatal error occurs, the program writes the error message to
|
||||||
stderr and exits. The caller should expect that a suitable error
|
stderr and exits. The caller should expect that a suitable error
|
||||||
message has been printed if the child closes the connection without
|
message has been printed if the child closes the connection without
|
||||||
@ -57,10 +93,49 @@ CAPABILITIES
|
|||||||
'fetch'::
|
'fetch'::
|
||||||
This helper supports the 'fetch' command.
|
This helper supports the 'fetch' command.
|
||||||
|
|
||||||
|
'option'::
|
||||||
|
This helper supports the option command.
|
||||||
|
|
||||||
|
'push'::
|
||||||
|
This helper supports the 'push' command.
|
||||||
|
|
||||||
REF LIST ATTRIBUTES
|
REF LIST ATTRIBUTES
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
None are defined yet, but the caller must accept any which are supplied.
|
'for-push'::
|
||||||
|
The caller wants to use the ref list to prepare push
|
||||||
|
commands. A helper might chose to acquire the ref list by
|
||||||
|
opening a different type of connection to the destination.
|
||||||
|
|
||||||
|
OPTIONS
|
||||||
|
-------
|
||||||
|
'option verbosity' <N>::
|
||||||
|
Change the level of messages displayed by the helper.
|
||||||
|
When N is 0 the end-user has asked the process to be
|
||||||
|
quiet, and the helper should produce only error output.
|
||||||
|
N of 1 is the default level of verbosity, higher values
|
||||||
|
of N correspond to the number of -v flags passed on the
|
||||||
|
command line.
|
||||||
|
|
||||||
|
'option progress' \{'true'|'false'\}::
|
||||||
|
Enable (or disable) progress messages displayed by the
|
||||||
|
transport helper during a command.
|
||||||
|
|
||||||
|
'option depth' <depth>::
|
||||||
|
Deepen the history of a shallow repository.
|
||||||
|
|
||||||
|
'option followtags' \{'true'|'false'\}::
|
||||||
|
If enabled the helper should automatically fetch annotated
|
||||||
|
tag objects if the object the tag points at was transferred
|
||||||
|
during the fetch command. If the tag is not fetched by
|
||||||
|
the helper a second fetch command will usually be sent to
|
||||||
|
ask for the tag specifically. Some helpers may be able to
|
||||||
|
use this option to avoid a second network connection.
|
||||||
|
|
||||||
|
'option dry-run' \{'true'|'false'\}:
|
||||||
|
If true, pretend the operation completed successfully,
|
||||||
|
but don't actually change any repository data. For most
|
||||||
|
helpers this only applies to the 'push', if supported.
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
-------------
|
-------------
|
||||||
|
@ -13,10 +13,10 @@ SYNOPSIS
|
|||||||
'git remote add' [-t <branch>] [-m <master>] [-f] [--mirror] <name> <url>
|
'git remote add' [-t <branch>] [-m <master>] [-f] [--mirror] <name> <url>
|
||||||
'git remote rename' <old> <new>
|
'git remote rename' <old> <new>
|
||||||
'git remote rm' <name>
|
'git remote rm' <name>
|
||||||
'git remote set-head' <name> [-a | -d | <branch>]
|
'git remote set-head' <name> (-a | -d | <branch>)
|
||||||
'git remote show' [-n] <name>
|
'git remote' [-v | --verbose] 'show' [-n] <name>
|
||||||
'git remote prune' [-n | --dry-run] <name>
|
'git remote prune' [-n | --dry-run] <name>
|
||||||
'git remote update' [-p | --prune] [group | remote]...
|
'git remote' [-v | --verbose] 'update' [-p | --prune] [group | remote]...
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
@ -30,6 +30,7 @@ OPTIONS
|
|||||||
-v::
|
-v::
|
||||||
--verbose::
|
--verbose::
|
||||||
Be a little more verbose and show remote url after name.
|
Be a little more verbose and show remote url after name.
|
||||||
|
NOTE: This must be placed between `remote` and `subcommand`.
|
||||||
|
|
||||||
|
|
||||||
COMMANDS
|
COMMANDS
|
||||||
|
@ -17,12 +17,36 @@ DESCRIPTION
|
|||||||
Adds a 'replace' reference in `.git/refs/replace/`
|
Adds a 'replace' reference in `.git/refs/replace/`
|
||||||
|
|
||||||
The name of the 'replace' reference is the SHA1 of the object that is
|
The name of the 'replace' reference is the SHA1 of the object that is
|
||||||
replaced. The content of the replace reference is the SHA1 of the
|
replaced. The content of the 'replace' reference is the SHA1 of the
|
||||||
replacement object.
|
replacement object.
|
||||||
|
|
||||||
Unless `-f` is given, the replace reference must not yet exist in
|
Unless `-f` is given, the 'replace' reference must not yet exist in
|
||||||
`.git/refs/replace/` directory.
|
`.git/refs/replace/` directory.
|
||||||
|
|
||||||
|
Replacement references will be used by default by all git commands
|
||||||
|
except those doing reachability traversal (prune, pack transfer and
|
||||||
|
fsck).
|
||||||
|
|
||||||
|
It is possible to disable use of replacement references for any
|
||||||
|
command using the `--no-replace-objects` option just after 'git'.
|
||||||
|
|
||||||
|
For example if commit 'foo' has been replaced by commit 'bar':
|
||||||
|
|
||||||
|
------------------------------------------------
|
||||||
|
$ git --no-replace-objects cat-file commit foo
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
shows information about commit 'foo', while:
|
||||||
|
|
||||||
|
------------------------------------------------
|
||||||
|
$ git cat-file commit foo
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
shows information about commit 'bar'.
|
||||||
|
|
||||||
|
The 'GIT_NO_REPLACE_OBJECTS' environment variable can be set to
|
||||||
|
achieve the same effect as the `--no-replace-objects` option.
|
||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
-------
|
-------
|
||||||
-f::
|
-f::
|
||||||
@ -54,6 +78,7 @@ SEE ALSO
|
|||||||
--------
|
--------
|
||||||
linkgit:git-tag[1]
|
linkgit:git-tag[1]
|
||||||
linkgit:git-branch[1]
|
linkgit:git-branch[1]
|
||||||
|
linkgit:git[1]
|
||||||
|
|
||||||
Author
|
Author
|
||||||
------
|
------
|
||||||
|
@ -150,7 +150,7 @@ Automatic merge failed; fix conflicts and then commit the result.
|
|||||||
$ git reset --hard <2>
|
$ git reset --hard <2>
|
||||||
$ git pull . topic/branch <3>
|
$ git pull . topic/branch <3>
|
||||||
Updating from 41223... to 13134...
|
Updating from 41223... to 13134...
|
||||||
Fast forward
|
Fast-forward
|
||||||
$ git reset --hard ORIG_HEAD <4>
|
$ git reset --hard ORIG_HEAD <4>
|
||||||
------------
|
------------
|
||||||
+
|
+
|
||||||
@ -161,7 +161,7 @@ right now, so you decide to do that later.
|
|||||||
which is a synonym for "git reset --hard HEAD" clears the mess
|
which is a synonym for "git reset --hard HEAD" clears the mess
|
||||||
from the index file and the working tree.
|
from the index file and the working tree.
|
||||||
<3> Merge a topic branch into the current branch, which resulted
|
<3> Merge a topic branch into the current branch, which resulted
|
||||||
in a fast forward.
|
in a fast-forward.
|
||||||
<4> But you decided that the topic branch is not ready for public
|
<4> But you decided that the topic branch is not ready for public
|
||||||
consumption yet. "pull" or "merge" always leaves the original
|
consumption yet. "pull" or "merge" always leaves the original
|
||||||
tip of the current branch in ORIG_HEAD, so resetting hard to it
|
tip of the current branch in ORIG_HEAD, so resetting hard to it
|
||||||
|
@ -60,8 +60,8 @@ The --bcc option must be repeated for each user you want on the bcc list.
|
|||||||
The --cc option must be repeated for each user you want on the cc list.
|
The --cc option must be repeated for each user you want on the cc list.
|
||||||
|
|
||||||
--compose::
|
--compose::
|
||||||
Use $GIT_EDITOR, core.editor, $VISUAL, or $EDITOR to edit an
|
Invoke a text editor (see GIT_EDITOR in linkgit:git-var[1])
|
||||||
introductory message for the patch series.
|
to edit an introductory message for the patch series.
|
||||||
+
|
+
|
||||||
When '--compose' is used, git send-email will use the From, Subject, and
|
When '--compose' is used, git send-email will use the From, Subject, and
|
||||||
In-Reply-To headers specified in the message. If the body of the message
|
In-Reply-To headers specified in the message. If the body of the message
|
||||||
|
@ -105,11 +105,11 @@ name. See linkgit:git-rev-parse[1].
|
|||||||
|
|
||||||
Without '--force', the <src> ref is stored at the remote only if
|
Without '--force', the <src> ref is stored at the remote only if
|
||||||
<dst> does not exist, or <dst> is a proper subset (i.e. an
|
<dst> does not exist, or <dst> is a proper subset (i.e. an
|
||||||
ancestor) of <src>. This check, known as "fast forward check",
|
ancestor) of <src>. This check, known as "fast-forward check",
|
||||||
is performed in order to avoid accidentally overwriting the
|
is performed in order to avoid accidentally overwriting the
|
||||||
remote ref and lose other peoples' commits from there.
|
remote ref and lose other peoples' commits from there.
|
||||||
|
|
||||||
With '--force', the fast forward check is disabled for all refs.
|
With '--force', the fast-forward check is disabled for all refs.
|
||||||
|
|
||||||
Optionally, a <ref> parameter can be prefixed with a plus '+' sign
|
Optionally, a <ref> parameter can be prefixed with a plus '+' sign
|
||||||
to disable the fast-forward check only on that ref.
|
to disable the fast-forward check only on that ref.
|
||||||
|
@ -8,7 +8,7 @@ git-show-ref - List references in a local repository
|
|||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
[verse]
|
[verse]
|
||||||
'git show-ref' [-q|--quiet] [--verify] [-h|--head] [-d|--dereference]
|
'git show-ref' [-q|--quiet] [--verify] [--head] [-d|--dereference]
|
||||||
[-s|--hash[=<n>]] [--abbrev[=<n>]] [--tags]
|
[-s|--hash[=<n>]] [--abbrev[=<n>]] [--tags]
|
||||||
[--heads] [--] <pattern>...
|
[--heads] [--] <pattern>...
|
||||||
'git show-ref' --exclude-existing[=<pattern>] < ref-list
|
'git show-ref' --exclude-existing[=<pattern>] < ref-list
|
||||||
@ -30,7 +30,6 @@ the `.git` directory.
|
|||||||
OPTIONS
|
OPTIONS
|
||||||
-------
|
-------
|
||||||
|
|
||||||
-h::
|
|
||||||
--head::
|
--head::
|
||||||
|
|
||||||
Show the HEAD reference.
|
Show the HEAD reference.
|
||||||
|
@ -10,7 +10,7 @@ SYNOPSIS
|
|||||||
--------
|
--------
|
||||||
[verse]
|
[verse]
|
||||||
'git submodule' [--quiet] add [-b branch]
|
'git submodule' [--quiet] add [-b branch]
|
||||||
[--reference <repository>] [--] <repository> <path>
|
[--reference <repository>] [--] <repository> [<path>]
|
||||||
'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...]
|
'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...]
|
||||||
'git submodule' [--quiet] init [--] [<path>...]
|
'git submodule' [--quiet] init [--] [<path>...]
|
||||||
'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase]
|
'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase]
|
||||||
@ -69,7 +69,11 @@ add::
|
|||||||
to the changeset to be committed next to the current
|
to the changeset to be committed next to the current
|
||||||
project: the current project is termed the "superproject".
|
project: the current project is termed the "superproject".
|
||||||
+
|
+
|
||||||
This requires two arguments: <repository> and <path>.
|
This requires at least one argument: <repository>. The optional
|
||||||
|
argument <path> is the relative location for the cloned submodule
|
||||||
|
to exist in the superproject. If <path> is not given, the
|
||||||
|
"humanish" part of the source repository is used ("repo" for
|
||||||
|
"/path/to/repo.git" and "foo" for "host.xz:foo/.git").
|
||||||
+
|
+
|
||||||
<repository> is the URL of the new submodule's origin repository.
|
<repository> is the URL of the new submodule's origin repository.
|
||||||
This may be either an absolute URL, or (if it begins with ./
|
This may be either an absolute URL, or (if it begins with ./
|
||||||
|
@ -320,6 +320,13 @@ Any other arguments are passed directly to 'git log'
|
|||||||
directories. The output is suitable for appending to
|
directories. The output is suitable for appending to
|
||||||
the $GIT_DIR/info/exclude file.
|
the $GIT_DIR/info/exclude file.
|
||||||
|
|
||||||
|
'mkdirs'::
|
||||||
|
Attempts to recreate empty directories that core git cannot track
|
||||||
|
based on information in $GIT_DIR/svn/<refname>/unhandled.log files.
|
||||||
|
Empty directories are automatically recreated when using
|
||||||
|
"git svn clone" and "git svn rebase", so "mkdirs" is intended
|
||||||
|
for use after commands like "git checkout" or "git reset".
|
||||||
|
|
||||||
'commit-diff'::
|
'commit-diff'::
|
||||||
Commits the diff of two tree-ish arguments from the
|
Commits the diff of two tree-ish arguments from the
|
||||||
command-line. This command does not rely on being inside an `git svn
|
command-line. This command does not rely on being inside an `git svn
|
||||||
@ -735,6 +742,16 @@ merges you've made. Furthermore, if you merge or pull from a git branch
|
|||||||
that is a mirror of an SVN branch, 'dcommit' may commit to the wrong
|
that is a mirror of an SVN branch, 'dcommit' may commit to the wrong
|
||||||
branch.
|
branch.
|
||||||
|
|
||||||
|
If you do merge, note the following rule: 'git svn dcommit' will
|
||||||
|
attempt to commit on top of the SVN commit named in
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
git log --grep=^git-svn-id: --first-parent -1
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
You 'must' therefore ensure that the most recent commit of the branch
|
||||||
|
you want to dcommit to is the 'first' parent of the merge. Chaos will
|
||||||
|
ensue otherwise, especially if the first parent is an older commit on
|
||||||
|
the same SVN branch.
|
||||||
|
|
||||||
'git clone' does not clone branches under the refs/remotes/ hierarchy or
|
'git clone' does not clone branches under the refs/remotes/ hierarchy or
|
||||||
any 'git svn' metadata, or config. So repositories created and managed with
|
any 'git svn' metadata, or config. So repositories created and managed with
|
||||||
using 'git svn' should use 'rsync' for cloning, if cloning is to be done
|
using 'git svn' should use 'rsync' for cloning, if cloning is to be done
|
||||||
|
@ -99,6 +99,10 @@ in the index e.g. when merging in a commit;
|
|||||||
thus, in case the assumed-untracked file is changed upstream,
|
thus, in case the assumed-untracked file is changed upstream,
|
||||||
you will need to handle the situation manually.
|
you will need to handle the situation manually.
|
||||||
|
|
||||||
|
--really-refresh::
|
||||||
|
Like '--refresh', but checks stat information unconditionally,
|
||||||
|
without regard to the "assume unchanged" setting.
|
||||||
|
|
||||||
-g::
|
-g::
|
||||||
--again::
|
--again::
|
||||||
Runs 'git-update-index' itself on the paths whose index
|
Runs 'git-update-index' itself on the paths whose index
|
||||||
@ -308,7 +312,7 @@ Configuration
|
|||||||
-------------
|
-------------
|
||||||
|
|
||||||
The command honors `core.filemode` configuration variable. If
|
The command honors `core.filemode` configuration variable. If
|
||||||
your repository is on an filesystem whose executable bits are
|
your repository is on a filesystem whose executable bits are
|
||||||
unreliable, this should be set to 'false' (see linkgit:git-config[1]).
|
unreliable, this should be set to 'false' (see linkgit:git-config[1]).
|
||||||
This causes the command to ignore differences in file modes recorded
|
This causes the command to ignore differences in file modes recorded
|
||||||
in the index and the file mode on the filesystem if they differ only on
|
in the index and the file mode on the filesystem if they differ only on
|
||||||
|
@ -36,6 +36,20 @@ GIT_AUTHOR_IDENT::
|
|||||||
GIT_COMMITTER_IDENT::
|
GIT_COMMITTER_IDENT::
|
||||||
The person who put a piece of code into git.
|
The person who put a piece of code into git.
|
||||||
|
|
||||||
|
GIT_EDITOR::
|
||||||
|
Text editor for use by git commands. The value is meant to be
|
||||||
|
interpreted by the shell when it is used. Examples: `~/bin/vi`,
|
||||||
|
`$SOME_ENVIRONMENT_VARIABLE`, `"C:\Program Files\Vim\gvim.exe"
|
||||||
|
--nofork`. The order of preference is the `$GIT_EDITOR`
|
||||||
|
environment variable, then `core.editor` configuration, then
|
||||||
|
`$VISUAL`, then `$EDITOR`, and then finally 'vi'.
|
||||||
|
|
||||||
|
GIT_PAGER::
|
||||||
|
Text viewer for use by git commands (e.g., 'less'). The value
|
||||||
|
is meant to be interpreted by the shell. The order of preference
|
||||||
|
is the `$GIT_PAGER` environment variable, then `core.pager`
|
||||||
|
configuration, then `$PAGER`, and then finally 'less'.
|
||||||
|
|
||||||
Diagnostics
|
Diagnostics
|
||||||
-----------
|
-----------
|
||||||
You don't exist. Go away!::
|
You don't exist. Go away!::
|
||||||
|
@ -10,7 +10,7 @@ SYNOPSIS
|
|||||||
--------
|
--------
|
||||||
[verse]
|
[verse]
|
||||||
'git' [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path]
|
'git' [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path]
|
||||||
[-p|--paginate|--no-pager]
|
[-p|--paginate|--no-pager] [--no-replace-objects]
|
||||||
[--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE]
|
[--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE]
|
||||||
[--help] COMMAND [ARGS]
|
[--help] COMMAND [ARGS]
|
||||||
|
|
||||||
@ -43,9 +43,12 @@ unreleased) version of git, that is available from 'master'
|
|||||||
branch of the `git.git` repository.
|
branch of the `git.git` repository.
|
||||||
Documentation for older releases are available here:
|
Documentation for older releases are available here:
|
||||||
|
|
||||||
* link:v1.6.5/git.html[documentation for release 1.6.5]
|
* link:v1.6.5.3/git.html[documentation for release 1.6.5.3]
|
||||||
|
|
||||||
* release notes for
|
* release notes for
|
||||||
|
link:RelNotes-1.6.5.3.txt[1.6.5.3],
|
||||||
|
link:RelNotes-1.6.5.2.txt[1.6.5.2],
|
||||||
|
link:RelNotes-1.6.5.1.txt[1.6.5.1],
|
||||||
link:RelNotes-1.6.5.txt[1.6.5].
|
link:RelNotes-1.6.5.txt[1.6.5].
|
||||||
|
|
||||||
* link:v1.6.4.4/git.html[documentation for release 1.6.4.4]
|
* link:v1.6.4.4/git.html[documentation for release 1.6.4.4]
|
||||||
@ -237,6 +240,10 @@ help ...`.
|
|||||||
environment is not set, it is set to the current working
|
environment is not set, it is set to the current working
|
||||||
directory.
|
directory.
|
||||||
|
|
||||||
|
--no-replace-objects::
|
||||||
|
Do not use replacement refs to replace git objects. See
|
||||||
|
linkgit:git-replace[1] for more information.
|
||||||
|
|
||||||
|
|
||||||
FURTHER DOCUMENTATION
|
FURTHER DOCUMENTATION
|
||||||
---------------------
|
---------------------
|
||||||
|
@ -560,6 +560,16 @@ in the file. E.g. the string `$Format:%H$` will be replaced by the
|
|||||||
commit hash.
|
commit hash.
|
||||||
|
|
||||||
|
|
||||||
|
Packing objects
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
`delta`
|
||||||
|
^^^^^^^
|
||||||
|
|
||||||
|
Delta compression will not be attempted for blobs for paths with the
|
||||||
|
attribute `delta` set to false.
|
||||||
|
|
||||||
|
|
||||||
Viewing files in GUI tools
|
Viewing files in GUI tools
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ object is. git will tell you that you have a "blob" object (i.e., just a
|
|||||||
regular file), and you can see the contents with
|
regular file), and you can see the contents with
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
$ git cat-file "blob" 557db03
|
$ git cat-file blob 557db03
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
which will print out "Hello World". The object `557db03` is nothing
|
which will print out "Hello World". The object `557db03` is nothing
|
||||||
@ -993,7 +993,7 @@ would be different)
|
|||||||
|
|
||||||
----------------
|
----------------
|
||||||
Updating from ae3a2da... to a80b4aa....
|
Updating from ae3a2da... to a80b4aa....
|
||||||
Fast forward (no commit created; -m option ignored)
|
Fast-forward (no commit created; -m option ignored)
|
||||||
example | 1 +
|
example | 1 +
|
||||||
hello | 1 +
|
hello | 1 +
|
||||||
2 files changed, 2 insertions(+), 0 deletions(-)
|
2 files changed, 2 insertions(+), 0 deletions(-)
|
||||||
@ -1003,7 +1003,7 @@ Because your branch did not contain anything more than what had
|
|||||||
already been merged into the `master` branch, the merge operation did
|
already been merged into the `master` branch, the merge operation did
|
||||||
not actually do a merge. Instead, it just updated the top of
|
not actually do a merge. Instead, it just updated the top of
|
||||||
the tree of your branch to that of the `master` branch. This is
|
the tree of your branch to that of the `master` branch. This is
|
||||||
often called 'fast forward' merge.
|
often called 'fast-forward' merge.
|
||||||
|
|
||||||
You can run `gitk \--all` again to see how the commit ancestry
|
You can run `gitk \--all` again to see how the commit ancestry
|
||||||
looks like, or run 'show-branch', which tells you this.
|
looks like, or run 'show-branch', which tells you this.
|
||||||
@ -1186,9 +1186,9 @@ $ git show-branch
|
|||||||
* [master] Some fun.
|
* [master] Some fun.
|
||||||
! [mybranch] Some work.
|
! [mybranch] Some work.
|
||||||
--
|
--
|
||||||
+ [mybranch] Some work.
|
|
||||||
* [master] Some fun.
|
* [master] Some fun.
|
||||||
*+ [mybranch^] New day.
|
+ [mybranch] Some work.
|
||||||
|
*+ [master^] Initial commit
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Now we are ready to experiment with the merge by hand.
|
Now we are ready to experiment with the merge by hand.
|
||||||
@ -1204,11 +1204,11 @@ $ mb=$(git merge-base HEAD mybranch)
|
|||||||
The command writes the commit object name of the common ancestor
|
The command writes the commit object name of the common ancestor
|
||||||
to the standard output, so we captured its output to a variable,
|
to the standard output, so we captured its output to a variable,
|
||||||
because we will be using it in the next step. By the way, the common
|
because we will be using it in the next step. By the way, the common
|
||||||
ancestor commit is the "New day." commit in this case. You can
|
ancestor commit is the "Initial commit" commit in this case. You can
|
||||||
tell it by:
|
tell it by:
|
||||||
|
|
||||||
------------
|
------------
|
||||||
$ git name-rev $mb
|
$ git name-rev --name-only --tags $mb
|
||||||
my-first-tag
|
my-first-tag
|
||||||
------------
|
------------
|
||||||
|
|
||||||
@ -1237,8 +1237,8 @@ inspect the index file with this command:
|
|||||||
------------
|
------------
|
||||||
$ git ls-files --stage
|
$ git ls-files --stage
|
||||||
100644 7f8b141b65fdcee47321e399a2598a235a032422 0 example
|
100644 7f8b141b65fdcee47321e399a2598a235a032422 0 example
|
||||||
100644 263414f423d0e4d70dae8fe53fa34614ff3e2860 1 hello
|
100644 557db03de997c86a4a028e1ebd3a1ceb225be238 1 hello
|
||||||
100644 06fa6a24256dc7e560efa5687fa84b51f0263c3a 2 hello
|
100644 ba42a2a96e3027f3333e13ede4ccf4498c3ae942 2 hello
|
||||||
100644 cc44c73eb783565da5831b4d820c962954019b69 3 hello
|
100644 cc44c73eb783565da5831b4d820c962954019b69 3 hello
|
||||||
------------
|
------------
|
||||||
|
|
||||||
@ -1253,8 +1253,8 @@ To look at only non-zero stages, use `\--unmerged` flag:
|
|||||||
|
|
||||||
------------
|
------------
|
||||||
$ git ls-files --unmerged
|
$ git ls-files --unmerged
|
||||||
100644 263414f423d0e4d70dae8fe53fa34614ff3e2860 1 hello
|
100644 557db03de997c86a4a028e1ebd3a1ceb225be238 1 hello
|
||||||
100644 06fa6a24256dc7e560efa5687fa84b51f0263c3a 2 hello
|
100644 ba42a2a96e3027f3333e13ede4ccf4498c3ae942 2 hello
|
||||||
100644 cc44c73eb783565da5831b4d820c962954019b69 3 hello
|
100644 cc44c73eb783565da5831b4d820c962954019b69 3 hello
|
||||||
------------
|
------------
|
||||||
|
|
||||||
@ -1283,8 +1283,8 @@ the working tree.. This can be seen if you run `ls-files
|
|||||||
------------
|
------------
|
||||||
$ git ls-files --stage
|
$ git ls-files --stage
|
||||||
100644 7f8b141b65fdcee47321e399a2598a235a032422 0 example
|
100644 7f8b141b65fdcee47321e399a2598a235a032422 0 example
|
||||||
100644 263414f423d0e4d70dae8fe53fa34614ff3e2860 1 hello
|
100644 557db03de997c86a4a028e1ebd3a1ceb225be238 1 hello
|
||||||
100644 06fa6a24256dc7e560efa5687fa84b51f0263c3a 2 hello
|
100644 ba42a2a96e3027f3333e13ede4ccf4498c3ae942 2 hello
|
||||||
100644 cc44c73eb783565da5831b4d820c962954019b69 3 hello
|
100644 cc44c73eb783565da5831b4d820c962954019b69 3 hello
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ from updating that ref.
|
|||||||
This hook can be used to prevent 'forced' update on certain refs by
|
This hook can be used to prevent 'forced' update on certain refs by
|
||||||
making sure that the object name is a commit object that is a
|
making sure that the object name is a commit object that is a
|
||||||
descendant of the commit object named by the old object name.
|
descendant of the commit object named by the old object name.
|
||||||
That is, to enforce a "fast forward only" policy.
|
That is, to enforce a "fast-forward only" policy.
|
||||||
|
|
||||||
It could also be used to log the old..new status. However, it
|
It could also be used to log the old..new status. However, it
|
||||||
does not know the entire set of branches, so it would end up
|
does not know the entire set of branches, so it would end up
|
||||||
|
@ -209,6 +209,121 @@ chance to see if their in-progress work will be compatible. `git.git`
|
|||||||
has such an official throw-away integration branch called 'pu'.
|
has such an official throw-away integration branch called 'pu'.
|
||||||
|
|
||||||
|
|
||||||
|
Branch management for a release
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Assuming you are using the merge approach discussed above, when you
|
||||||
|
are releasing your project you will need to do some additional branch
|
||||||
|
management work.
|
||||||
|
|
||||||
|
A feature release is created from the 'master' branch, since 'master'
|
||||||
|
tracks the commits that should go into the next feature release.
|
||||||
|
|
||||||
|
The 'master' branch is supposed to be a superset of 'maint'. If this
|
||||||
|
condition does not hold, then 'maint' contains some commits that
|
||||||
|
are not included on 'master'. The fixes represented by those commits
|
||||||
|
will therefore not be included in your feature release.
|
||||||
|
|
||||||
|
To verify that 'master' is indeed a superset of 'maint', use git log:
|
||||||
|
|
||||||
|
.Verify 'master' is a superset of 'maint'
|
||||||
|
[caption="Recipe: "]
|
||||||
|
=====================================
|
||||||
|
`git log master..maint`
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
This command should not list any commits. Otherwise, check out
|
||||||
|
'master' and merge 'maint' into it.
|
||||||
|
|
||||||
|
Now you can proceed with the creation of the feature release. Apply a
|
||||||
|
tag to the tip of 'master' indicating the release version:
|
||||||
|
|
||||||
|
.Release tagging
|
||||||
|
[caption="Recipe: "]
|
||||||
|
=====================================
|
||||||
|
`git tag -s -m "GIT X.Y.Z" vX.Y.Z master`
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
You need to push the new tag to a public git server (see
|
||||||
|
"DISTRIBUTED WORKFLOWS" below). This makes the tag available to
|
||||||
|
others tracking your project. The push could also trigger a
|
||||||
|
post-update hook to perform release-related items such as building
|
||||||
|
release tarballs and preformatted documentation pages.
|
||||||
|
|
||||||
|
Similarly, for a maintenance release, 'maint' is tracking the commits
|
||||||
|
to be released. Therefore, in the steps above simply tag and push
|
||||||
|
'maint' rather than 'master'.
|
||||||
|
|
||||||
|
|
||||||
|
Maintenance branch management after a feature release
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
After a feature release, you need to manage your maintenance branches.
|
||||||
|
|
||||||
|
First, if you wish to continue to release maintenance fixes for the
|
||||||
|
feature release made before the recent one, then you must create
|
||||||
|
another branch to track commits for that previous release.
|
||||||
|
|
||||||
|
To do this, the current maintenance branch is copied to another branch
|
||||||
|
named with the previous release version number (e.g. maint-X.Y.(Z-1)
|
||||||
|
where X.Y.Z is the current release).
|
||||||
|
|
||||||
|
.Copy maint
|
||||||
|
[caption="Recipe: "]
|
||||||
|
=====================================
|
||||||
|
`git branch maint-X.Y.(Z-1) maint`
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
The 'maint' branch should now be fast-forwarded to the newly released
|
||||||
|
code so that maintenance fixes can be tracked for the current release:
|
||||||
|
|
||||||
|
.Update maint to new release
|
||||||
|
[caption="Recipe: "]
|
||||||
|
=====================================
|
||||||
|
* `git checkout maint`
|
||||||
|
* `git merge --ff-only master`
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
If the merge fails because it is not a fast-forward, then it is
|
||||||
|
possible some fixes on 'maint' were missed in the feature release.
|
||||||
|
This will not happen if the content of the branches was verified as
|
||||||
|
described in the previous section.
|
||||||
|
|
||||||
|
|
||||||
|
Branch management for next and pu after a feature release
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
After a feature release, the integration branch 'next' may optionally be
|
||||||
|
rewound and rebuilt from the tip of 'master' using the surviving
|
||||||
|
topics on 'next':
|
||||||
|
|
||||||
|
.Rewind and rebuild next
|
||||||
|
[caption="Recipe: "]
|
||||||
|
=====================================
|
||||||
|
* `git checkout next`
|
||||||
|
* `git reset --hard master`
|
||||||
|
* `git merge ai/topic_in_next1`
|
||||||
|
* `git merge ai/topic_in_next2`
|
||||||
|
* ...
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
The advantage of doing this is that the history of 'next' will be
|
||||||
|
clean. For example, some topics merged into 'next' may have initially
|
||||||
|
looked promising, but were later found to be undesirable or premature.
|
||||||
|
In such a case, the topic is reverted out of 'next' but the fact
|
||||||
|
remains in the history that it was once merged and reverted. By
|
||||||
|
recreating 'next', you give another incarnation of such topics a clean
|
||||||
|
slate to retry, and a feature release is a good point in history to do
|
||||||
|
so.
|
||||||
|
|
||||||
|
If you do this, then you should make a public announcement indicating
|
||||||
|
that 'next' was rewound and rebuilt.
|
||||||
|
|
||||||
|
The same rewind and rebuild process may be followed for 'pu'. A public
|
||||||
|
announcement is not necessary since 'pu' is a throw-away branch, as
|
||||||
|
described above.
|
||||||
|
|
||||||
|
|
||||||
DISTRIBUTED WORKFLOWS
|
DISTRIBUTED WORKFLOWS
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ to point at the new commit.
|
|||||||
An evil merge is a <<def_merge,merge>> that introduces changes that
|
An evil merge is a <<def_merge,merge>> that introduces changes that
|
||||||
do not appear in any <<def_parent,parent>>.
|
do not appear in any <<def_parent,parent>>.
|
||||||
|
|
||||||
[[def_fast_forward]]fast forward::
|
[[def_fast_forward]]fast-forward::
|
||||||
A fast-forward is a special type of <<def_merge,merge>> where you have a
|
A fast-forward is a special type of <<def_merge,merge>> where you have a
|
||||||
<<def_revision,revision>> and you are "merging" another
|
<<def_revision,revision>> and you are "merging" another
|
||||||
<<def_branch,branch>>'s changes that happen to be a descendant of what
|
<<def_branch,branch>>'s changes that happen to be a descendant of what
|
||||||
@ -220,7 +220,7 @@ to point at the new commit.
|
|||||||
conflict, manual intervention may be required to complete the
|
conflict, manual intervention may be required to complete the
|
||||||
merge.
|
merge.
|
||||||
+
|
+
|
||||||
As a noun: unless it is a <<def_fast_forward,fast forward>>, a
|
As a noun: unless it is a <<def_fast_forward,fast-forward>>, a
|
||||||
successful merge results in the creation of a new <<def_commit,commit>>
|
successful merge results in the creation of a new <<def_commit,commit>>
|
||||||
representing the result of the merge, and having as
|
representing the result of the merge, and having as
|
||||||
<<def_parent,parents>> the tips of the merged <<def_branch,branches>>.
|
<<def_parent,parents>> the tips of the merged <<def_branch,branches>>.
|
||||||
|
@ -59,7 +59,7 @@ The policy.
|
|||||||
not yet pass the criteria set for 'next'.
|
not yet pass the criteria set for 'next'.
|
||||||
|
|
||||||
- The tips of 'master', 'maint' and 'next' branches will always
|
- The tips of 'master', 'maint' and 'next' branches will always
|
||||||
fast forward, to allow people to build their own
|
fast-forward, to allow people to build their own
|
||||||
customization on top of them.
|
customization on top of them.
|
||||||
|
|
||||||
- Usually 'master' contains all of 'maint', 'next' contains all
|
- Usually 'master' contains all of 'maint', 'next' contains all
|
||||||
|
@ -85,7 +85,7 @@ Fortunately I did not have to; what I have in the current branch
|
|||||||
|
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
$ git checkout master
|
$ git checkout master
|
||||||
$ git merge revert-c99 ;# this should be a fast forward
|
$ git merge revert-c99 ;# this should be a fast-forward
|
||||||
Updating from 10d781b9caa4f71495c7b34963bef137216f86a8 to e3a693c...
|
Updating from 10d781b9caa4f71495c7b34963bef137216f86a8 to e3a693c...
|
||||||
cache.h | 8 ++++----
|
cache.h | 8 ++++----
|
||||||
commit.c | 2 +-
|
commit.c | 2 +-
|
||||||
@ -95,7 +95,7 @@ Updating from 10d781b9caa4f71495c7b34963bef137216f86a8 to e3a693c...
|
|||||||
5 files changed, 8 insertions(+), 8 deletions(-)
|
5 files changed, 8 insertions(+), 8 deletions(-)
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
There is no need to redo the test at this point. We fast forwarded
|
There is no need to redo the test at this point. We fast-forwarded
|
||||||
and we know 'master' matches 'revert-c99' exactly. In fact:
|
and we know 'master' matches 'revert-c99' exactly. In fact:
|
||||||
|
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
@ -76,7 +76,7 @@ case "$1" in
|
|||||||
if expr "$2" : '0*$' >/dev/null; then
|
if expr "$2" : '0*$' >/dev/null; then
|
||||||
info "The branch '$1' is new..."
|
info "The branch '$1' is new..."
|
||||||
else
|
else
|
||||||
# updating -- make sure it is a fast forward
|
# updating -- make sure it is a fast-forward
|
||||||
mb=$(git-merge-base "$2" "$3")
|
mb=$(git-merge-base "$2" "$3")
|
||||||
case "$mb,$2" in
|
case "$mb,$2" in
|
||||||
"$2,$mb") info "Update is fast-forward" ;;
|
"$2,$mb") info "Update is fast-forward" ;;
|
||||||
|
16
Documentation/manpage-quote-apos.xsl
Normal file
16
Documentation/manpage-quote-apos.xsl
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||||
|
version="1.0">
|
||||||
|
|
||||||
|
<!-- work around newer groff/man setups using a prettier apostrophe
|
||||||
|
that unfortunately does not quote anything when cut&pasting
|
||||||
|
examples to the shell -->
|
||||||
|
<xsl:template name="escape.apostrophe">
|
||||||
|
<xsl:param name="content"/>
|
||||||
|
<xsl:call-template name="string.subst">
|
||||||
|
<xsl:with-param name="string" select="$content"/>
|
||||||
|
<xsl:with-param name="target">'</xsl:with-param>
|
||||||
|
<xsl:with-param name="replacement">\(aq</xsl:with-param>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
</xsl:stylesheet>
|
@ -23,7 +23,7 @@ merge.tool::
|
|||||||
Controls which merge resolution program is used by
|
Controls which merge resolution program is used by
|
||||||
linkgit:git-mergetool[1]. Valid built-in values are: "kdiff3",
|
linkgit:git-mergetool[1]. Valid built-in values are: "kdiff3",
|
||||||
"tkdiff", "meld", "xxdiff", "emerge", "vimdiff", "gvimdiff",
|
"tkdiff", "meld", "xxdiff", "emerge", "vimdiff", "gvimdiff",
|
||||||
"diffuse", "ecmerge", "tortoisemerge", "araxis", and
|
"diffuse", "ecmerge", "tortoisemerge", "p4merge", "araxis" and
|
||||||
"opendiff". Any other value is treated is custom merge tool
|
"opendiff". Any other value is treated is custom merge tool
|
||||||
and there must be a corresponding mergetool.<tool>.cmd option.
|
and there must be a corresponding mergetool.<tool>.cmd option.
|
||||||
|
|
||||||
|
@ -1,43 +1,42 @@
|
|||||||
-q::
|
--commit::
|
||||||
--quiet::
|
--no-commit::
|
||||||
Operate quietly.
|
Perform the merge and commit the result. This option can
|
||||||
|
be used to override --no-commit.
|
||||||
|
+
|
||||||
|
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.
|
||||||
|
|
||||||
-v::
|
--ff::
|
||||||
--verbose::
|
--no-ff::
|
||||||
Be verbose.
|
Do not generate a merge commit if the merge resolved as
|
||||||
|
a fast-forward, only update the branch pointer. This is
|
||||||
--stat::
|
the default behavior of git-merge.
|
||||||
Show a diffstat at the end of the merge. The diffstat is also
|
+
|
||||||
controlled by the configuration option merge.stat.
|
With --no-ff Generate a merge commit even if the merge
|
||||||
|
resolved as a fast-forward.
|
||||||
-n::
|
|
||||||
--no-stat::
|
|
||||||
Do not show a diffstat at the end of the merge.
|
|
||||||
|
|
||||||
--summary::
|
|
||||||
--no-summary::
|
|
||||||
Synonyms to --stat and --no-stat; these are deprecated and will be
|
|
||||||
removed in the future.
|
|
||||||
|
|
||||||
--log::
|
--log::
|
||||||
|
--no-log::
|
||||||
In addition to branch names, populate the log message with
|
In addition to branch names, populate the log message with
|
||||||
one-line descriptions from the actual commits that are being
|
one-line descriptions from the actual commits that are being
|
||||||
merged.
|
merged.
|
||||||
|
+
|
||||||
|
With --no-log do not list one-line descriptions from the
|
||||||
|
actual commits being merged.
|
||||||
|
|
||||||
--no-log::
|
|
||||||
Do not list one-line descriptions from the actual commits being
|
|
||||||
merged.
|
|
||||||
|
|
||||||
--no-commit::
|
--stat::
|
||||||
Perform the merge but pretend the merge failed and do
|
-n::
|
||||||
not autocommit, to give the user a chance to inspect and
|
--no-stat::
|
||||||
further tweak the merge result before committing.
|
Show a diffstat at the end of the merge. The diffstat is also
|
||||||
|
controlled by the configuration option merge.stat.
|
||||||
--commit::
|
+
|
||||||
Perform the merge and commit the result. This option can
|
With -n or --no-stat do not show a diffstat at the end of the
|
||||||
be used to override --no-commit.
|
merge.
|
||||||
|
|
||||||
--squash::
|
--squash::
|
||||||
|
--no-squash::
|
||||||
Produce the working tree and index state as if a real
|
Produce the working tree and index state as if a real
|
||||||
merge happened (except for the merge information),
|
merge happened (except for the merge information),
|
||||||
but do not actually make a commit or
|
but do not actually make a commit or
|
||||||
@ -46,19 +45,14 @@
|
|||||||
commit. This allows you to create a single commit on
|
commit. This allows you to create a single commit on
|
||||||
top of the current branch whose effect is the same as
|
top of the current branch whose effect is the same as
|
||||||
merging another branch (or more in case of an octopus).
|
merging another branch (or more in case of an octopus).
|
||||||
|
+
|
||||||
|
With --no-squash perform the merge and commit the result. This
|
||||||
|
option can be used to override --squash.
|
||||||
|
|
||||||
--no-squash::
|
--ff-only::
|
||||||
Perform the merge and commit the result. This option can
|
Refuse to merge and exit with a non-zero status unless the
|
||||||
be used to override --squash.
|
current `HEAD` is already up-to-date or the merge can be
|
||||||
|
resolved as a fast-forward.
|
||||||
--no-ff::
|
|
||||||
Generate a merge commit even if the merge resolved as a
|
|
||||||
fast-forward.
|
|
||||||
|
|
||||||
--ff::
|
|
||||||
Do not generate a merge commit if the merge resolved as
|
|
||||||
a fast-forward, only update the branch pointer. This is
|
|
||||||
the default behavior of git-merge.
|
|
||||||
|
|
||||||
-s <strategy>::
|
-s <strategy>::
|
||||||
--strategy=<strategy>::
|
--strategy=<strategy>::
|
||||||
@ -67,3 +61,16 @@
|
|||||||
If there is no `-s` option, a built-in list of strategies
|
If there is no `-s` option, a built-in list of strategies
|
||||||
is used instead ('git-merge-recursive' when merging a single
|
is used instead ('git-merge-recursive' when merging a single
|
||||||
head, 'git-merge-octopus' otherwise).
|
head, 'git-merge-octopus' otherwise).
|
||||||
|
|
||||||
|
--summary::
|
||||||
|
--no-summary::
|
||||||
|
Synonyms to --stat and --no-stat; these are deprecated and will be
|
||||||
|
removed in the future.
|
||||||
|
|
||||||
|
-q::
|
||||||
|
--quiet::
|
||||||
|
Operate quietly.
|
||||||
|
|
||||||
|
-v::
|
||||||
|
--verbose::
|
||||||
|
Be verbose.
|
||||||
|
@ -29,8 +29,9 @@ octopus::
|
|||||||
pulling or merging more than one branch.
|
pulling or merging more than one branch.
|
||||||
|
|
||||||
ours::
|
ours::
|
||||||
This resolves any number of heads, but the result of the
|
This resolves any number of heads, but the resulting tree of the
|
||||||
merge is always the current branch head. It is meant to
|
merge is always that of the current branch head, effectively
|
||||||
|
ignoring all changes from all other branches. It is meant to
|
||||||
be used to supersede old development history of side
|
be used to supersede old development history of side
|
||||||
branches.
|
branches.
|
||||||
|
|
||||||
|
@ -123,6 +123,10 @@ The placeholders are:
|
|||||||
- '%s': subject
|
- '%s': subject
|
||||||
- '%f': sanitized subject line, suitable for a filename
|
- '%f': sanitized subject line, suitable for a filename
|
||||||
- '%b': body
|
- '%b': body
|
||||||
|
- '%N': commit notes
|
||||||
|
- '%gD': reflog selector, e.g., `refs/stash@\{1\}`
|
||||||
|
- '%gd': shortened reflog selector, e.g., `stash@\{1\}`
|
||||||
|
- '%gs': reflog subject
|
||||||
- '%Cred': switch color to red
|
- '%Cred': switch color to red
|
||||||
- '%Cgreen': switch color to green
|
- '%Cgreen': switch color to green
|
||||||
- '%Cblue': switch color to blue
|
- '%Cblue': switch color to blue
|
||||||
@ -131,6 +135,14 @@ The placeholders are:
|
|||||||
- '%m': left, right or boundary mark
|
- '%m': left, right or boundary mark
|
||||||
- '%n': newline
|
- '%n': newline
|
||||||
- '%x00': print a byte from a hex code
|
- '%x00': print a byte from a hex code
|
||||||
|
- '%w([<w>[,<i1>[,<i2>]]])': switch line wrapping, like the -w option of
|
||||||
|
linkgit:git-shortlog[1].
|
||||||
|
|
||||||
|
NOTE: Some placeholders may depend on other options given to the
|
||||||
|
revision traversal engine. For example, the `%g*` reflog options will
|
||||||
|
insert an empty string unless we are traversing reflog entries (e.g., by
|
||||||
|
`git log -g`). The `%d` placeholder will use the "short" decoration
|
||||||
|
format if `--decorate` was not already provided on the command line.
|
||||||
|
|
||||||
* 'tformat:'
|
* 'tformat:'
|
||||||
+
|
+
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
gittutorial(7)
|
gittutorial(7)
|
||||||
==============
|
==============
|
||||||
|
|
||||||
NAME
|
NOME
|
||||||
----
|
----
|
||||||
gittutorial - Um tutorial de introdução ao git (para versão 1.5.1 ou mais nova)
|
gittutorial - Um tutorial de introdução ao git (para versão 1.5.1 ou mais nova)
|
||||||
|
|
||||||
SYNOPSIS
|
SINOPSE
|
||||||
--------
|
--------
|
||||||
git *
|
git *
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIÇÃO
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
Este tutorial explica como importar um novo projeto para o git,
|
Este tutorial explica como importar um novo projeto para o git,
|
||||||
@ -64,11 +64,11 @@ Git irá responder
|
|||||||
Initialized empty Git repository in .git/
|
Initialized empty Git repository in .git/
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
Você agora iniciou seu diretório de trabalho--você deve ter notado um
|
Agora que você iniciou seu diretório de trabalho, você deve ter notado que um
|
||||||
novo diretório criado, com o nome de ".git".
|
novo diretório foi criado com o nome de ".git".
|
||||||
|
|
||||||
A seguir, diga ao git para gravar um instantâneo do conteúdo de todos os
|
A seguir, diga ao git para gravar um instantâneo do conteúdo de todos os
|
||||||
arquivos sob o diretório corrente (note o '.'), com 'git-add':
|
arquivos sob o diretório atual (note o '.'), com 'git-add':
|
||||||
|
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
$ git add .
|
$ git add .
|
||||||
@ -126,8 +126,8 @@ mudanças com:
|
|||||||
$ git commit
|
$ git commit
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
Isto irá novamente te pedir por uma mensagem descrevendo a mudança, e,
|
Ao executar esse comando, ele irá te pedir uma mensagem descrevendo a mudança,
|
||||||
então, gravar a nova versão do projeto.
|
e, então, irá gravar a nova versão do projeto.
|
||||||
|
|
||||||
Alternativamente, ao invés de executar 'git-add' antes, você pode usar
|
Alternativamente, ao invés de executar 'git-add' antes, você pode usar
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ idéia começar a mensagem com uma simples e curta (menos de 50
|
|||||||
caracteres) linha sumarizando a mudança, seguida de uma linha em branco
|
caracteres) linha sumarizando a mudança, seguida de uma linha em branco
|
||||||
e, então, uma descrição mais detalhada. Ferramentas que transformam
|
e, então, uma descrição mais detalhada. Ferramentas que transformam
|
||||||
commits em email, por exemplo, usam a primeira linha no campo de
|
commits em email, por exemplo, usam a primeira linha no campo de
|
||||||
cabeçalho Subject: e o resto no corpo.
|
cabeçalho "Subject:" e o resto no corpo.
|
||||||
|
|
||||||
Git rastreia conteúdo, não arquivos
|
Git rastreia conteúdo, não arquivos
|
||||||
----------------------------
|
----------------------------
|
||||||
@ -155,7 +155,7 @@ usado tanto para arquivos novos e arquivos recentemente modificados, e
|
|||||||
em ambos os casos, ele tira o instantâneo dos arquivos dados e armazena
|
em ambos os casos, ele tira o instantâneo dos arquivos dados e armazena
|
||||||
o conteúdo no índice, pronto para inclusão do próximo commit.
|
o conteúdo no índice, pronto para inclusão do próximo commit.
|
||||||
|
|
||||||
Visualizando história do projeto
|
Visualizando a história do projeto
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
Em qualquer ponto você pode visualizar a história das suas mudanças
|
Em qualquer ponto você pode visualizar a história das suas mudanças
|
||||||
@ -165,7 +165,7 @@ usando
|
|||||||
$ git log
|
$ git log
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
Se você também quer ver a diferença completa a cada passo, use
|
Se você também quiser ver a diferença completa a cada passo, use
|
||||||
|
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
$ git log -p
|
$ git log -p
|
||||||
|
@ -4,6 +4,13 @@
|
|||||||
(see the section <<URLS,GIT URLS>> below) or the name
|
(see the section <<URLS,GIT URLS>> below) or the name
|
||||||
of a remote (see the section <<REMOTES,REMOTES>> below).
|
of a remote (see the section <<REMOTES,REMOTES>> below).
|
||||||
|
|
||||||
|
ifndef::git-pull[]
|
||||||
|
<group>::
|
||||||
|
A name referring to a list of repositories as the value
|
||||||
|
of remotes.<group> in the configuration file.
|
||||||
|
(See linkgit:git-config[1]).
|
||||||
|
endif::git-pull[]
|
||||||
|
|
||||||
<refspec>::
|
<refspec>::
|
||||||
The format of a <refspec> parameter is an optional plus
|
The format of a <refspec> parameter is an optional plus
|
||||||
`{plus}`, followed by the source ref <src>, followed
|
`{plus}`, followed by the source ref <src>, followed
|
||||||
@ -11,9 +18,9 @@
|
|||||||
+
|
+
|
||||||
The remote ref that matches <src>
|
The remote ref that matches <src>
|
||||||
is fetched, and if <dst> is not empty string, the local
|
is fetched, and if <dst> is not empty string, the local
|
||||||
ref that matches it is fast forwarded using <src>.
|
ref that matches it is fast-forwarded using <src>.
|
||||||
If the optional plus `+` is used, the local ref
|
If the optional plus `+` is used, the local ref
|
||||||
is updated even if it does not result in a fast forward
|
is updated even if it does not result in a fast-forward
|
||||||
update.
|
update.
|
||||||
+
|
+
|
||||||
[NOTE]
|
[NOTE]
|
||||||
|
@ -243,12 +243,23 @@ endif::git-rev-list[]
|
|||||||
Pretend as if all the refs in `$GIT_DIR/refs/remotes` are listed
|
Pretend as if all the refs in `$GIT_DIR/refs/remotes` are listed
|
||||||
on the command line as '<commit>'.
|
on the command line as '<commit>'.
|
||||||
|
|
||||||
ifdef::git-rev-list[]
|
ifndef::git-rev-list[]
|
||||||
|
--bisect::
|
||||||
|
|
||||||
|
Pretend as if the bad bisection ref `$GIT_DIR/refs/bisect/bad`
|
||||||
|
was listed and as if it was followed by `--not` and the good
|
||||||
|
bisection refs `$GIT_DIR/refs/bisect/good-*` on the command
|
||||||
|
line.
|
||||||
|
endif::git-rev-list[]
|
||||||
|
|
||||||
--stdin::
|
--stdin::
|
||||||
|
|
||||||
In addition to the '<commit>' listed on the command
|
In addition to the '<commit>' listed on the command
|
||||||
line, read them from the standard input.
|
line, read them from the standard input. If a '--' separator is
|
||||||
|
seen, stop reading commits and start reading paths to limit the
|
||||||
|
result.
|
||||||
|
|
||||||
|
ifdef::git-rev-list[]
|
||||||
--quiet::
|
--quiet::
|
||||||
|
|
||||||
Don't print anything to standard output. This form
|
Don't print anything to standard output. This form
|
||||||
@ -536,7 +547,11 @@ Bisection Helpers
|
|||||||
--bisect::
|
--bisect::
|
||||||
|
|
||||||
Limit output to the one commit object which is roughly halfway between
|
Limit output to the one commit object which is roughly halfway between
|
||||||
the included and excluded commits. Thus, if
|
included and excluded commits. Note that the bad bisection ref
|
||||||
|
`$GIT_DIR/refs/bisect/bad` is added to the included commits (if it
|
||||||
|
exists) and the good bisection refs `$GIT_DIR/refs/bisect/good-*` are
|
||||||
|
added to the excluded commits (if they exist). Thus, supposing there
|
||||||
|
are no refs in `$GIT_DIR/refs/bisect/`, if
|
||||||
|
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
$ git rev-list --bisect foo ^bar ^baz
|
$ git rev-list --bisect foo ^bar ^baz
|
||||||
@ -556,22 +571,24 @@ one.
|
|||||||
|
|
||||||
--bisect-vars::
|
--bisect-vars::
|
||||||
|
|
||||||
This calculates the same as `--bisect`, but outputs text ready
|
This calculates the same as `--bisect`, except that refs in
|
||||||
to be eval'ed by the shell. These lines will assign the name of
|
`$GIT_DIR/refs/bisect/` are not used, and except that this outputs
|
||||||
the midpoint revision to the variable `bisect_rev`, and the
|
text ready to be eval'ed by the shell. These lines will assign the
|
||||||
expected number of commits to be tested after `bisect_rev` is
|
name of the midpoint revision to the variable `bisect_rev`, and the
|
||||||
tested to `bisect_nr`, the expected number of commits to be
|
expected number of commits to be tested after `bisect_rev` is tested
|
||||||
tested if `bisect_rev` turns out to be good to `bisect_good`,
|
to `bisect_nr`, the expected number of commits to be tested if
|
||||||
the expected number of commits to be tested if `bisect_rev`
|
`bisect_rev` turns out to be good to `bisect_good`, the expected
|
||||||
turns out to be bad to `bisect_bad`, and the number of commits
|
number of commits to be tested if `bisect_rev` turns out to be bad to
|
||||||
we are bisecting right now to `bisect_all`.
|
`bisect_bad`, and the number of commits we are bisecting right now to
|
||||||
|
`bisect_all`.
|
||||||
|
|
||||||
--bisect-all::
|
--bisect-all::
|
||||||
|
|
||||||
This outputs all the commit objects between the included and excluded
|
This outputs all the commit objects between the included and excluded
|
||||||
commits, ordered by their distance to the included and excluded
|
commits, ordered by their distance to the included and excluded
|
||||||
commits. The farthest from them is displayed first. (This is the only
|
commits. Refs in `$GIT_DIR/refs/bisect/` are not used. The farthest
|
||||||
one displayed by `--bisect`.)
|
from them is displayed first. (This is the only one displayed by
|
||||||
|
`--bisect`.)
|
||||||
+
|
+
|
||||||
This is useful because it makes it easy to choose a good commit to
|
This is useful because it makes it easy to choose a good commit to
|
||||||
test when you want to avoid to test some of them for some reason (they
|
test when you want to avoid to test some of them for some reason (they
|
||||||
|
@ -11,9 +11,6 @@ Core functions:
|
|||||||
|
|
||||||
* `graph_init()` creates a new `struct git_graph`
|
* `graph_init()` creates a new `struct git_graph`
|
||||||
|
|
||||||
* `graph_release()` destroys a `struct git_graph`, and frees the memory
|
|
||||||
associated with it.
|
|
||||||
|
|
||||||
* `graph_update()` moves the graph to a new commit.
|
* `graph_update()` moves the graph to a new commit.
|
||||||
|
|
||||||
* `graph_next_line()` outputs the next line of the graph into a strbuf. It
|
* `graph_next_line()` outputs the next line of the graph into a strbuf. It
|
||||||
@ -134,8 +131,6 @@ while ((commit = get_revision(opts)) != NULL) {
|
|||||||
putchar(opts->diffopt.line_termination);
|
putchar(opts->diffopt.line_termination);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
graph_release(graph);
|
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Sample output
|
Sample output
|
||||||
|
@ -1,41 +1,494 @@
|
|||||||
Pack transfer protocols
|
Packfile transfer protocols
|
||||||
=======================
|
===========================
|
||||||
|
|
||||||
There are two Pack push-pull protocols.
|
Git supports transferring data in packfiles over the ssh://, git:// and
|
||||||
|
file:// transports. There exist two sets of protocols, one for pushing
|
||||||
|
data from a client to a server and another for fetching data from a
|
||||||
|
server to a client. All three transports (ssh, git, file) use the same
|
||||||
|
protocol to transfer data.
|
||||||
|
|
||||||
upload-pack (S) | fetch/clone-pack (C) protocol:
|
The processes invoked in the canonical Git implementation are 'upload-pack'
|
||||||
|
on the server side and 'fetch-pack' on the client side for fetching data;
|
||||||
|
then 'receive-pack' on the server and 'send-pack' on the client for pushing
|
||||||
|
data. The protocol functions to have a server tell a client what is
|
||||||
|
currently on the server, then for the two to negotiate the smallest amount
|
||||||
|
of data to send in order to fully update one or the other.
|
||||||
|
|
||||||
# Tell the puller what commits we have and what their names are
|
Transports
|
||||||
S: SHA1 name
|
----------
|
||||||
S: ...
|
There are three transports over which the packfile protocol is
|
||||||
S: SHA1 name
|
initiated. The Git transport is a simple, unauthenticated server that
|
||||||
S: # flush -- it's your turn
|
takes the command (almost always 'upload-pack', though Git
|
||||||
# Tell the pusher what commits we want, and what we have
|
servers can be configured to be globally writable, in which 'receive-
|
||||||
C: want name
|
pack' initiation is also allowed) with which the client wishes to
|
||||||
C: ..
|
communicate and executes it and connects it to the requesting
|
||||||
C: want name
|
process.
|
||||||
C: have SHA1
|
|
||||||
C: have SHA1
|
|
||||||
C: ...
|
|
||||||
C: # flush -- occasionally ask "had enough?"
|
|
||||||
S: NAK
|
|
||||||
C: have SHA1
|
|
||||||
C: ...
|
|
||||||
C: have SHA1
|
|
||||||
S: ACK
|
|
||||||
C: done
|
|
||||||
S: XXXXXXX -- packfile contents.
|
|
||||||
|
|
||||||
send-pack | receive-pack protocol.
|
In the SSH transport, the client just runs the 'upload-pack'
|
||||||
|
or 'receive-pack' process on the server over the SSH protocol and then
|
||||||
|
communicates with that invoked process over the SSH connection.
|
||||||
|
|
||||||
# Tell the pusher what commits we have and what their names are
|
The file:// transport runs the 'upload-pack' or 'receive-pack'
|
||||||
C: SHA1 name
|
process locally and communicates with it over a pipe.
|
||||||
C: ...
|
|
||||||
C: SHA1 name
|
Git Transport
|
||||||
C: # flush -- it's your turn
|
-------------
|
||||||
# Tell the puller what the pusher has
|
|
||||||
S: old-SHA1 new-SHA1 name
|
The Git transport starts off by sending the command and repository
|
||||||
S: old-SHA1 new-SHA1 name
|
on the wire using the pkt-line format, followed by a NUL byte and a
|
||||||
S: ...
|
hostname paramater, terminated by a NUL byte.
|
||||||
S: # flush -- done with the list
|
|
||||||
S: XXXXXXX --- packfile contents.
|
0032git-upload-pack /project.git\0host=myserver.com\0
|
||||||
|
|
||||||
|
--
|
||||||
|
git-proto-request = request-command SP pathname NUL [ host-parameter NUL ]
|
||||||
|
request-command = "git-upload-pack" / "git-receive-pack" /
|
||||||
|
"git-upload-archive" ; case sensitive
|
||||||
|
pathname = *( %x01-ff ) ; exclude NUL
|
||||||
|
host-parameter = "host=" hostname [ ":" port ]
|
||||||
|
--
|
||||||
|
|
||||||
|
Only host-parameter is allowed in the git-proto-request. Clients
|
||||||
|
MUST NOT attempt to send additional parameters. It is used for the
|
||||||
|
git-daemon name based virtual hosting. See --interpolated-path
|
||||||
|
option to git daemon, with the %H/%CH format characters.
|
||||||
|
|
||||||
|
Basically what the Git client is doing to connect to an 'upload-pack'
|
||||||
|
process on the server side over the Git protocol is this:
|
||||||
|
|
||||||
|
$ echo -e -n \
|
||||||
|
"0039git-upload-pack /schacon/gitbook.git\0host=example.com\0" |
|
||||||
|
nc -v example.com 9418
|
||||||
|
|
||||||
|
|
||||||
|
SSH Transport
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Initiating the upload-pack or receive-pack processes over SSH is
|
||||||
|
executing the binary on the server via SSH remote execution.
|
||||||
|
It is basically equivalent to running this:
|
||||||
|
|
||||||
|
$ ssh git.example.com "git-upload-pack '/project.git'"
|
||||||
|
|
||||||
|
For a server to support Git pushing and pulling for a given user over
|
||||||
|
SSH, that user needs to be able to execute one or both of those
|
||||||
|
commands via the SSH shell that they are provided on login. On some
|
||||||
|
systems, that shell access is limited to only being able to run those
|
||||||
|
two commands, or even just one of them.
|
||||||
|
|
||||||
|
In an ssh:// format URI, it's absolute in the URI, so the '/' after
|
||||||
|
the host name (or port number) is sent as an argument, which is then
|
||||||
|
read by the remote git-upload-pack exactly as is, so it's effectively
|
||||||
|
an absolute path in the remote filesystem.
|
||||||
|
|
||||||
|
git clone ssh://user@example.com/project.git
|
||||||
|
|
|
||||||
|
v
|
||||||
|
ssh user@example.com "git-upload-pack '/project.git'"
|
||||||
|
|
||||||
|
In a "user@host:path" format URI, its relative to the user's home
|
||||||
|
directory, because the Git client will run:
|
||||||
|
|
||||||
|
git clone user@example.com:project.git
|
||||||
|
|
|
||||||
|
v
|
||||||
|
ssh user@example.com "git-upload-pack 'project.git'"
|
||||||
|
|
||||||
|
The exception is if a '~' is used, in which case
|
||||||
|
we execute it without the leading '/'.
|
||||||
|
|
||||||
|
ssh://user@example.com/~alice/project.git,
|
||||||
|
|
|
||||||
|
v
|
||||||
|
ssh user@example.com "git-upload-pack '~alice/project.git'"
|
||||||
|
|
||||||
|
A few things to remember here:
|
||||||
|
|
||||||
|
- The "command name" is spelled with dash (e.g. git-upload-pack), but
|
||||||
|
this can be overridden by the client;
|
||||||
|
|
||||||
|
- The repository path is always quoted with single quotes.
|
||||||
|
|
||||||
|
Fetching Data From a Server
|
||||||
|
===========================
|
||||||
|
|
||||||
|
When one Git repository wants to get data that a second repository
|
||||||
|
has, the first can 'fetch' from the second. This operation determines
|
||||||
|
what data the server has that the client does not then streams that
|
||||||
|
data down to the client in packfile format.
|
||||||
|
|
||||||
|
|
||||||
|
Reference Discovery
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
When the client initially connects the server will immediately respond
|
||||||
|
with a listing of each reference it has (all branches and tags) along
|
||||||
|
with the object name that each reference currently points to.
|
||||||
|
|
||||||
|
$ echo -e -n "0039git-upload-pack /schacon/gitbook.git\0host=example.com\0" |
|
||||||
|
nc -v example.com 9418
|
||||||
|
00887217a7c7e582c46cec22a130adf4b9d7d950fba0 HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow no-progress include-tag
|
||||||
|
00441d3fcd5ced445d1abc402225c0b8a1299641f497 refs/heads/integration
|
||||||
|
003f7217a7c7e582c46cec22a130adf4b9d7d950fba0 refs/heads/master
|
||||||
|
003cb88d2441cac0977faf98efc80305012112238d9d refs/tags/v0.9
|
||||||
|
003c525128480b96c89e6418b1e40909bf6c5b2d580f refs/tags/v1.0
|
||||||
|
003fe92df48743b7bc7d26bcaabfddde0a1e20cae47c refs/tags/v1.0^{}
|
||||||
|
0000
|
||||||
|
|
||||||
|
Server SHOULD terminate each non-flush line using LF ("\n") terminator;
|
||||||
|
client MUST NOT complain if there is no terminator.
|
||||||
|
|
||||||
|
The returned response is a pkt-line stream describing each ref and
|
||||||
|
its current value. The stream MUST be sorted by name according to
|
||||||
|
the C locale ordering.
|
||||||
|
|
||||||
|
If HEAD is a valid ref, HEAD MUST appear as the first advertised
|
||||||
|
ref. If HEAD is not a valid ref, HEAD MUST NOT appear in the
|
||||||
|
advertisement list at all, but other refs may still appear.
|
||||||
|
|
||||||
|
The stream MUST include capability declarations behind a NUL on the
|
||||||
|
first ref. The peeled value of a ref (that is "ref^{}") MUST be
|
||||||
|
immediately after the ref itself, if presented. A conforming server
|
||||||
|
MUST peel the ref if its an annotated tag.
|
||||||
|
|
||||||
|
----
|
||||||
|
advertised-refs = (no-refs / list-of-refs)
|
||||||
|
flush-pkt
|
||||||
|
|
||||||
|
no-refs = PKT-LINE(zero-id SP "capabilities^{}"
|
||||||
|
NUL capability-list LF)
|
||||||
|
|
||||||
|
list-of-refs = first-ref *other-ref
|
||||||
|
first-ref = PKT-LINE(obj-id SP refname
|
||||||
|
NUL capability-list LF)
|
||||||
|
|
||||||
|
other-ref = PKT-LINE(other-tip / other-peeled)
|
||||||
|
other-tip = obj-id SP refname LF
|
||||||
|
other-peeled = obj-id SP refname "^{}" LF
|
||||||
|
|
||||||
|
capability-list = capability *(SP capability)
|
||||||
|
capability = 1*(LC_ALPHA / DIGIT / "-" / "_")
|
||||||
|
LC_ALPHA = %x61-7A
|
||||||
|
----
|
||||||
|
|
||||||
|
Server and client MUST use lowercase for obj-id, both MUST treat obj-id
|
||||||
|
as case-insensitive.
|
||||||
|
|
||||||
|
See protocol-capabilities.txt for a list of allowed server capabilities
|
||||||
|
and descriptions.
|
||||||
|
|
||||||
|
Packfile Negotiation
|
||||||
|
--------------------
|
||||||
|
After reference and capabilities discovery, the client can decide
|
||||||
|
to terminate the connection by sending a flush-pkt, telling the
|
||||||
|
server it can now gracefully terminate (as happens with the ls-remote
|
||||||
|
command) or it can enter the negotiation phase, where the client and
|
||||||
|
server determine what the minimal packfile necessary for transport is.
|
||||||
|
|
||||||
|
Once the client has the initial list of references that the server
|
||||||
|
has, as well as the list of capabilities, it will begin telling the
|
||||||
|
server what objects it wants and what objects it has, so the server
|
||||||
|
can make a packfile that only contains the objects that the client needs.
|
||||||
|
The client will also send a list of the capabilities it wants to be in
|
||||||
|
effect, out of what the server said it could do with the first 'want' line.
|
||||||
|
|
||||||
|
----
|
||||||
|
upload-request = want-list
|
||||||
|
have-list
|
||||||
|
compute-end
|
||||||
|
|
||||||
|
want-list = first-want
|
||||||
|
*additional-want
|
||||||
|
flush-pkt
|
||||||
|
|
||||||
|
first-want = PKT-LINE("want" SP obj-id SP capability-list LF)
|
||||||
|
additional-want = PKT-LINE("want" SP obj-id LF)
|
||||||
|
|
||||||
|
have-list = *have-line
|
||||||
|
have-line = PKT-LINE("have" SP obj-id LF)
|
||||||
|
compute-end = flush-pkt / PKT-LINE("done")
|
||||||
|
----
|
||||||
|
|
||||||
|
Clients MUST send all the obj-ids it wants from the reference
|
||||||
|
discovery phase as 'want' lines. Clients MUST send at least one
|
||||||
|
'want' command in the request body. Clients MUST NOT mention an
|
||||||
|
obj-id in a 'want' command which did not appear in the response
|
||||||
|
obtained through ref discovery.
|
||||||
|
|
||||||
|
If client is requesting a shallow clone, it will now send a 'deepen'
|
||||||
|
line with the depth it is requesting.
|
||||||
|
|
||||||
|
Once all the "want"s (and optional 'deepen') are transferred,
|
||||||
|
clients MUST send a flush-pkt. If the client has all the references
|
||||||
|
on the server, client flushes and disconnects.
|
||||||
|
|
||||||
|
TODO: shallow/unshallow response and document the deepen command in the ABNF.
|
||||||
|
|
||||||
|
Now the client will send a list of the obj-ids it has using 'have'
|
||||||
|
lines. In multi_ack mode, the canonical implementation will send up
|
||||||
|
to 32 of these at a time, then will send a flush-pkt. The canonical
|
||||||
|
implementation will skip ahead and send the next 32 immediately,
|
||||||
|
so that there is always a block of 32 "in-flight on the wire" at a
|
||||||
|
time.
|
||||||
|
|
||||||
|
If the server reads 'have' lines, it then will respond by ACKing any
|
||||||
|
of the obj-ids the client said it had that the server also has. The
|
||||||
|
server will ACK obj-ids differently depending on which ack mode is
|
||||||
|
chosen by the client.
|
||||||
|
|
||||||
|
In multi_ack mode:
|
||||||
|
|
||||||
|
* the server will respond with 'ACK obj-id continue' for any common
|
||||||
|
commits.
|
||||||
|
|
||||||
|
* once the server has found an acceptable common base commit and is
|
||||||
|
ready to make a packfile, it will blindly ACK all 'have' obj-ids
|
||||||
|
back to the client.
|
||||||
|
|
||||||
|
* the server will then send a 'NACK' and then wait for another response
|
||||||
|
from the client - either a 'done' or another list of 'have' lines.
|
||||||
|
|
||||||
|
In multi_ack_detailed mode:
|
||||||
|
|
||||||
|
* the server will differentiate the ACKs where it is signaling
|
||||||
|
that it is ready to send data with 'ACK obj-id ready' lines, and
|
||||||
|
signals the identified common commits with 'ACK obj-id common' lines.
|
||||||
|
|
||||||
|
Without either multi_ack or multi_ack_detailed:
|
||||||
|
|
||||||
|
* upload-pack sends "ACK obj-id" on the first common object it finds.
|
||||||
|
After that it says nothing until the client gives it a "done".
|
||||||
|
|
||||||
|
* upload-pack sends "NAK" on a flush-pkt if no common object
|
||||||
|
has been found yet. If one has been found, and thus an ACK
|
||||||
|
was already sent, its silent on the flush-pkt.
|
||||||
|
|
||||||
|
After the client has gotten enough ACK responses that it can determine
|
||||||
|
that the server has enough information to send an efficient packfile
|
||||||
|
(in the canonical implementation, this is determined when it has received
|
||||||
|
enough ACKs that it can color everything left in the --date-order queue
|
||||||
|
as common with the server, or the --date-order queue is empty), or the
|
||||||
|
client determines that it wants to give up (in the canonical implementation,
|
||||||
|
this is determined when the client sends 256 'have' lines without getting
|
||||||
|
any of them ACKed by the server - meaning there is nothing in common and
|
||||||
|
the server should just send all it's objects), then the client will send
|
||||||
|
a 'done' command. The 'done' command signals to the server that the client
|
||||||
|
is ready to receive it's packfile data.
|
||||||
|
|
||||||
|
However, the 256 limit *only* turns on in the canonical client
|
||||||
|
implementation if we have received at least one "ACK %s continue"
|
||||||
|
during a prior round. This helps to ensure that at least one common
|
||||||
|
ancestor is found before we give up entirely.
|
||||||
|
|
||||||
|
Once the 'done' line is read from the client, the server will either
|
||||||
|
send a final 'ACK obj-id' or it will send a 'NAK'. The server only sends
|
||||||
|
ACK after 'done' if there is at least one common base and multi_ack or
|
||||||
|
multi_ack_detailed is enabled. The server always sends NAK after 'done'
|
||||||
|
if there is no common base found.
|
||||||
|
|
||||||
|
Then the server will start sending it's packfile data.
|
||||||
|
|
||||||
|
----
|
||||||
|
server-response = *ack_multi ack / nak
|
||||||
|
ack_multi = PKT-LINE("ACK" SP obj-id ack_status LF)
|
||||||
|
ack_status = "continue" / "common" / "ready"
|
||||||
|
ack = PKT-LINE("ACK SP obj-id LF)
|
||||||
|
nak = PKT-LINE("NAK" LF)
|
||||||
|
----
|
||||||
|
|
||||||
|
A simple clone may look like this (with no 'have' lines):
|
||||||
|
|
||||||
|
----
|
||||||
|
C: 0054want 74730d410fcb6603ace96f1dc55ea6196122532d\0multi_ack \
|
||||||
|
side-band-64k ofs-delta\n
|
||||||
|
C: 0032want 7d1665144a3a975c05f1f43902ddaf084e784dbe\n
|
||||||
|
C: 0032want 5a3f6be755bbb7deae50065988cbfa1ffa9ab68a\n
|
||||||
|
C: 0032want 7e47fe2bd8d01d481f44d7af0531bd93d3b21c01\n
|
||||||
|
C: 0032want 74730d410fcb6603ace96f1dc55ea6196122532d\n
|
||||||
|
C: 0000
|
||||||
|
C: 0009done\n
|
||||||
|
|
||||||
|
S: 0008NAK\n
|
||||||
|
S: [PACKFILE]
|
||||||
|
----
|
||||||
|
|
||||||
|
An incremental update (fetch) response might look like this:
|
||||||
|
|
||||||
|
----
|
||||||
|
C: 0054want 74730d410fcb6603ace96f1dc55ea6196122532d\0multi_ack \
|
||||||
|
side-band-64k ofs-delta\n
|
||||||
|
C: 0032want 7d1665144a3a975c05f1f43902ddaf084e784dbe\n
|
||||||
|
C: 0032want 5a3f6be755bbb7deae50065988cbfa1ffa9ab68a\n
|
||||||
|
C: 0000
|
||||||
|
C: 0032have 7e47fe2bd8d01d481f44d7af0531bd93d3b21c01\n
|
||||||
|
C: [30 more have lines]
|
||||||
|
C: 0032have 74730d410fcb6603ace96f1dc55ea6196122532d\n
|
||||||
|
C: 0000
|
||||||
|
|
||||||
|
S: 003aACK 7e47fe2bd8d01d481f44d7af0531bd93d3b21c01 continue\n
|
||||||
|
S: 003aACK 74730d410fcb6603ace96f1dc55ea6196122532d continue\n
|
||||||
|
S: 0008NAK\n
|
||||||
|
|
||||||
|
C: 0009done\n
|
||||||
|
|
||||||
|
S: 003aACK 74730d410fcb6603ace96f1dc55ea6196122532d\n
|
||||||
|
S: [PACKFILE]
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
Packfile Data
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Now that the client and server have finished negotiation about what
|
||||||
|
the minimal amount of data that needs to be sent to the client is, the server
|
||||||
|
will construct and send the required data in packfile format.
|
||||||
|
|
||||||
|
See pack-format.txt for what the packfile itself actually looks like.
|
||||||
|
|
||||||
|
If 'side-band' or 'side-band-64k' capabilities have been specified by
|
||||||
|
the client, the server will send the packfile data multiplexed.
|
||||||
|
|
||||||
|
Each packet starting with the packet-line length of the amount of data
|
||||||
|
that follows, followed by a single byte specifying the sideband the
|
||||||
|
following data is coming in on.
|
||||||
|
|
||||||
|
In 'side-band' mode, it will send up to 999 data bytes plus 1 control
|
||||||
|
code, for a total of up to 1000 bytes in a pkt-line. In 'side-band-64k'
|
||||||
|
mode it will send up to 65519 data bytes plus 1 control code, for a
|
||||||
|
total of up to 65520 bytes in a pkt-line.
|
||||||
|
|
||||||
|
The sideband byte will be a '1', '2' or a '3'. Sideband '1' will contain
|
||||||
|
packfile data, sideband '2' will be used for progress information that the
|
||||||
|
client will generally print to stderr and sideband '3' is used for error
|
||||||
|
information.
|
||||||
|
|
||||||
|
If no 'side-band' capability was specified, the server will stream the
|
||||||
|
entire packfile without multiplexing.
|
||||||
|
|
||||||
|
|
||||||
|
Pushing Data To a Server
|
||||||
|
========================
|
||||||
|
|
||||||
|
Pushing data to a server will invoke the 'receive-pack' process on the
|
||||||
|
server, which will allow the client to tell it which references it should
|
||||||
|
update and then send all the data the server will need for those new
|
||||||
|
references to be complete. Once all the data is received and validated,
|
||||||
|
the server will then update its references to what the client specified.
|
||||||
|
|
||||||
|
Authentication
|
||||||
|
--------------
|
||||||
|
|
||||||
|
The protocol itself contains no authentication mechanisms. That is to be
|
||||||
|
handled by the transport, such as SSH, before the 'receive-pack' process is
|
||||||
|
invoked. If 'receive-pack' is configured over the Git transport, those
|
||||||
|
repositories will be writable by anyone who can access that port (9418) as
|
||||||
|
that transport is unauthenticated.
|
||||||
|
|
||||||
|
Reference Discovery
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
The reference discovery phase is done nearly the same way as it is in the
|
||||||
|
fetching protocol. Each reference obj-id and name on the server is sent
|
||||||
|
in packet-line format to the client, followed by a flush-pkt. The only
|
||||||
|
real difference is that the capability listing is different - the only
|
||||||
|
possible values are 'report-status', 'delete-refs' and 'ofs-delta'.
|
||||||
|
|
||||||
|
Reference Update Request and Packfile Transfer
|
||||||
|
----------------------------------------------
|
||||||
|
|
||||||
|
Once the client knows what references the server is at, it can send a
|
||||||
|
list of reference update requests. For each reference on the server
|
||||||
|
that it wants to update, it sends a line listing the obj-id currently on
|
||||||
|
the server, the obj-id the client would like to update it to and the name
|
||||||
|
of the reference.
|
||||||
|
|
||||||
|
This list is followed by a flush-pkt and then the packfile that should
|
||||||
|
contain all the objects that the server will need to complete the new
|
||||||
|
references.
|
||||||
|
|
||||||
|
----
|
||||||
|
update-request = command-list [pack-file]
|
||||||
|
|
||||||
|
command-list = PKT-LINE(command NUL capability-list LF)
|
||||||
|
*PKT-LINE(command LF)
|
||||||
|
flush-pkt
|
||||||
|
|
||||||
|
command = create / delete / update
|
||||||
|
create = zero-id SP new-id SP name
|
||||||
|
delete = old-id SP zero-id SP name
|
||||||
|
update = old-id SP new-id SP name
|
||||||
|
|
||||||
|
old-id = obj-id
|
||||||
|
new-id = obj-id
|
||||||
|
|
||||||
|
pack-file = "PACK" 28*(OCTET)
|
||||||
|
----
|
||||||
|
|
||||||
|
If the receiving end does not support delete-refs, the sending end MUST
|
||||||
|
NOT ask for delete command.
|
||||||
|
|
||||||
|
The pack-file MUST NOT be sent if the only command used is 'delete'.
|
||||||
|
|
||||||
|
A pack-file MUST be sent if either create or update command is used,
|
||||||
|
even if the server already has all the necessary objects. In this
|
||||||
|
case the client MUST send an empty pack-file. The only time this
|
||||||
|
is likely to happen is if the client is creating
|
||||||
|
a new branch or a tag that points to an existing obj-id.
|
||||||
|
|
||||||
|
The server will receive the packfile, unpack it, then validate each
|
||||||
|
reference that is being updated that it hasn't changed while the request
|
||||||
|
was being processed (the obj-id is still the same as the old-id), and
|
||||||
|
it will run any update hooks to make sure that the update is acceptable.
|
||||||
|
If all of that is fine, the server will then update the references.
|
||||||
|
|
||||||
|
Report Status
|
||||||
|
-------------
|
||||||
|
|
||||||
|
After receiving the pack data from the sender, the receiver sends a
|
||||||
|
report if 'report-status' capability is in effect.
|
||||||
|
It is a short listing of what happened in that update. It will first
|
||||||
|
list the status of the packfile unpacking as either 'unpack ok' or
|
||||||
|
'unpack [error]'. Then it will list the status for each of the references
|
||||||
|
that it tried to update. Each line is either 'ok [refname]' if the
|
||||||
|
update was successful, or 'ng [refname] [error]' if the update was not.
|
||||||
|
|
||||||
|
----
|
||||||
|
report-status = unpack-status
|
||||||
|
1*(command-status)
|
||||||
|
flush-pkt
|
||||||
|
|
||||||
|
unpack-status = PKT-LINE("unpack" SP unpack-result LF)
|
||||||
|
unpack-result = "ok" / error-msg
|
||||||
|
|
||||||
|
command-status = command-ok / command-fail
|
||||||
|
command-ok = PKT-LINE("ok" SP refname LF)
|
||||||
|
command-fail = PKT-LINE("ng" SP refname SP error-msg LF)
|
||||||
|
|
||||||
|
error-msg = 1*(OCTECT) ; where not "ok"
|
||||||
|
----
|
||||||
|
|
||||||
|
Updates can be unsuccessful for a number of reasons. The reference can have
|
||||||
|
changed since the reference discovery phase was originally sent, meaning
|
||||||
|
someone pushed in the meantime. The reference being pushed could be a
|
||||||
|
non-fast-forward reference and the update hooks or configuration could be
|
||||||
|
set to not allow that, etc. Also, some references can be updated while others
|
||||||
|
can be rejected.
|
||||||
|
|
||||||
|
An example client/server communication might look like this:
|
||||||
|
|
||||||
|
----
|
||||||
|
S: 007c74730d410fcb6603ace96f1dc55ea6196122532d refs/heads/local\0report-status delete-refs ofs-delta\n
|
||||||
|
S: 003e7d1665144a3a975c05f1f43902ddaf084e784dbe refs/heads/debug\n
|
||||||
|
S: 003f74730d410fcb6603ace96f1dc55ea6196122532d refs/heads/master\n
|
||||||
|
S: 003f74730d410fcb6603ace96f1dc55ea6196122532d refs/heads/team\n
|
||||||
|
S: 0000
|
||||||
|
|
||||||
|
C: 003e7d1665144a3a975c05f1f43902ddaf084e784dbe 74730d410fcb6603ace96f1dc55ea6196122532d refs/heads/debug\n
|
||||||
|
C: 003e74730d410fcb6603ace96f1dc55ea6196122532d 5a3f6be755bbb7deae50065988cbfa1ffa9ab68a refs/heads/master\n
|
||||||
|
C: 0000
|
||||||
|
C: [PACKDATA]
|
||||||
|
|
||||||
|
S: 000aunpack ok\n
|
||||||
|
S: 0014ok refs/heads/debug\n
|
||||||
|
S: 0026ng refs/heads/master non-fast-forward\n
|
||||||
|
----
|
||||||
|
187
Documentation/technical/protocol-capabilities.txt
Normal file
187
Documentation/technical/protocol-capabilities.txt
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
Git Protocol Capabilities
|
||||||
|
=========================
|
||||||
|
|
||||||
|
Servers SHOULD support all capabilities defined in this document.
|
||||||
|
|
||||||
|
On the very first line of the initial server response of either
|
||||||
|
receive-pack and upload-pack the first reference is followed by
|
||||||
|
a NUL byte and then a list of space delimited server capabilities.
|
||||||
|
These allow the server to declare what it can and cannot support
|
||||||
|
to the client.
|
||||||
|
|
||||||
|
Client will then send a space separated list of capabilities it wants
|
||||||
|
to be in effect. The client MUST NOT ask for capabilities the server
|
||||||
|
did not say it supports.
|
||||||
|
|
||||||
|
Server MUST diagnose and abort if capabilities it does not understand
|
||||||
|
was sent. Server MUST NOT ignore capabilities that client requested
|
||||||
|
and server advertised. As a consequence of these rules, server MUST
|
||||||
|
NOT advertise capabilities it does not understand.
|
||||||
|
|
||||||
|
The 'report-status' and 'delete-refs' capabilities are sent and
|
||||||
|
recognized by the receive-pack (push to server) process.
|
||||||
|
|
||||||
|
The 'ofs-delta' capability is sent and recognized by both upload-pack
|
||||||
|
and receive-pack protocols.
|
||||||
|
|
||||||
|
All other capabilities are only recognized by the upload-pack (fetch
|
||||||
|
from server) process.
|
||||||
|
|
||||||
|
multi_ack
|
||||||
|
---------
|
||||||
|
|
||||||
|
The 'multi_ack' capability allows the server to return "ACK obj-id
|
||||||
|
continue" as soon as it finds a commit that it can use as a common
|
||||||
|
base, between the client's wants and the client's have set.
|
||||||
|
|
||||||
|
By sending this early, the server can potentially head off the client
|
||||||
|
from walking any further down that particular branch of the client's
|
||||||
|
repository history. The client may still need to walk down other
|
||||||
|
branches, sending have lines for those, until the server has a
|
||||||
|
complete cut across the DAG, or the client has said "done".
|
||||||
|
|
||||||
|
Without multi_ack, a client sends have lines in --date-order until
|
||||||
|
the server has found a common base. That means the client will send
|
||||||
|
have lines that are already known by the server to be common, because
|
||||||
|
they overlap in time with another branch that the server hasn't found
|
||||||
|
a common base on yet.
|
||||||
|
|
||||||
|
For example suppose the client has commits in caps that the server
|
||||||
|
doesn't and the server has commits in lower case that the client
|
||||||
|
doesn't, as in the following diagram:
|
||||||
|
|
||||||
|
+---- u ---------------------- x
|
||||||
|
/ +----- y
|
||||||
|
/ /
|
||||||
|
a -- b -- c -- d -- E -- F
|
||||||
|
\
|
||||||
|
+--- Q -- R -- S
|
||||||
|
|
||||||
|
If the client wants x,y and starts out by saying have F,S, the server
|
||||||
|
doesn't know what F,S is. Eventually the client says "have d" and
|
||||||
|
the server sends "ACK d continue" to let the client know to stop
|
||||||
|
walking down that line (so don't send c-b-a), but its not done yet,
|
||||||
|
it needs a base for x. The client keeps going with S-R-Q, until a
|
||||||
|
gets reached, at which point the server has a clear base and it all
|
||||||
|
ends.
|
||||||
|
|
||||||
|
Without multi_ack the client would have sent that c-b-a chain anyway,
|
||||||
|
interleaved with S-R-Q.
|
||||||
|
|
||||||
|
thin-pack
|
||||||
|
---------
|
||||||
|
|
||||||
|
This capability means that the server can send a 'thin' pack, a pack
|
||||||
|
which does not contain base objects; if those base objects are available
|
||||||
|
on client side. Client requests 'thin-pack' capability when it
|
||||||
|
understands how to "thicken" it by adding required delta bases making
|
||||||
|
it self-contained.
|
||||||
|
|
||||||
|
Client MUST NOT request 'thin-pack' capability if it cannot turn a thin
|
||||||
|
pack into a self-contained pack.
|
||||||
|
|
||||||
|
|
||||||
|
side-band, side-band-64k
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
This capability means that server can send, and client understand multiplexed
|
||||||
|
progress reports and error info interleaved with the packfile itself.
|
||||||
|
|
||||||
|
These two options are mutually exclusive. A modern client always
|
||||||
|
favors 'side-band-64k'.
|
||||||
|
|
||||||
|
Either mode indicates that the packfile data will be streamed broken
|
||||||
|
up into packets of up to either 1000 bytes in the case of 'side_band',
|
||||||
|
or 65520 bytes in the case of 'side_band_64k'. Each packet is made up
|
||||||
|
of a leading 4-byte pkt-line length of how much data is in the packet,
|
||||||
|
followed by a 1-byte stream code, followed by the actual data.
|
||||||
|
|
||||||
|
The stream code can be one of:
|
||||||
|
|
||||||
|
1 - pack data
|
||||||
|
2 - progress messages
|
||||||
|
3 - fatal error message just before stream aborts
|
||||||
|
|
||||||
|
The "side-band-64k" capability came about as a way for newer clients
|
||||||
|
that can handle much larger packets to request packets that are
|
||||||
|
actually crammed nearly full, while maintaining backward compatibility
|
||||||
|
for the older clients.
|
||||||
|
|
||||||
|
Further, with side-band and its up to 1000-byte messages, it's actually
|
||||||
|
999 bytes of payload and 1 byte for the stream code. With side-band-64k,
|
||||||
|
same deal, you have up to 65519 bytes of data and 1 byte for the stream
|
||||||
|
code.
|
||||||
|
|
||||||
|
The client MUST send only maximum of one of "side-band" and "side-
|
||||||
|
band-64k". Server MUST diagnose it as an error if client requests
|
||||||
|
both.
|
||||||
|
|
||||||
|
ofs-delta
|
||||||
|
---------
|
||||||
|
|
||||||
|
Server can send, and client understand PACKv2 with delta refering to
|
||||||
|
its base by position in pack rather than by an obj-id. That is, they can
|
||||||
|
send/read OBJ_OFS_DELTA (aka type 6) in a packfile.
|
||||||
|
|
||||||
|
shallow
|
||||||
|
-------
|
||||||
|
|
||||||
|
This capability adds "deepen", "shallow" and "unshallow" commands to
|
||||||
|
the fetch-pack/upload-pack protocol so clients can request shallow
|
||||||
|
clones.
|
||||||
|
|
||||||
|
no-progress
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The client was started with "git clone -q" or something, and doesn't
|
||||||
|
want that side band 2. Basically the client just says "I do not
|
||||||
|
wish to receive stream 2 on sideband, so do not send it to me, and if
|
||||||
|
you did, I will drop it on the floor anyway". However, the sideband
|
||||||
|
channel 3 is still used for error responses.
|
||||||
|
|
||||||
|
include-tag
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The 'include-tag' capability is about sending annotated tags if we are
|
||||||
|
sending objects they point to. If we pack an object to the client, and
|
||||||
|
a tag object points exactly at that object, we pack the tag object too.
|
||||||
|
In general this allows a client to get all new annotated tags when it
|
||||||
|
fetches a branch, in a single network connection.
|
||||||
|
|
||||||
|
Clients MAY always send include-tag, hardcoding it into a request when
|
||||||
|
the server advertises this capability. The decision for a client to
|
||||||
|
request include-tag only has to do with the client's desires for tag
|
||||||
|
data, whether or not a server had advertised objects in the
|
||||||
|
refs/tags/* namespace.
|
||||||
|
|
||||||
|
Servers MUST pack the tags if their referrant is packed and the client
|
||||||
|
has requested include-tags.
|
||||||
|
|
||||||
|
Clients MUST be prepared for the case where a server has ignored
|
||||||
|
include-tag and has not actually sent tags in the pack. In such
|
||||||
|
cases the client SHOULD issue a subsequent fetch to acquire the tags
|
||||||
|
that include-tag would have otherwise given the client.
|
||||||
|
|
||||||
|
The server SHOULD send include-tag, if it supports it, regardless
|
||||||
|
of whether or not there are tags available.
|
||||||
|
|
||||||
|
report-status
|
||||||
|
-------------
|
||||||
|
|
||||||
|
The upload-pack process can receive a 'report-status' capability,
|
||||||
|
which tells it that the client wants a report of what happened after
|
||||||
|
a packfile upload and reference update. If the pushing client requests
|
||||||
|
this capability, after unpacking and updating references the server
|
||||||
|
will respond with whether the packfile unpacked successfully and if
|
||||||
|
each reference was updated successfully. If any of those were not
|
||||||
|
successful, it will send back an error message. See pack-protocol.txt
|
||||||
|
for example messages.
|
||||||
|
|
||||||
|
delete-refs
|
||||||
|
-----------
|
||||||
|
|
||||||
|
If the server sends back the 'delete-refs' capability, it means that
|
||||||
|
it is capable of accepting an zero-id value as the target
|
||||||
|
value of a reference update. It is not sent back by the client, it
|
||||||
|
simply informs the client that it can be sent zero-id values
|
||||||
|
to delete references.
|
96
Documentation/technical/protocol-common.txt
Normal file
96
Documentation/technical/protocol-common.txt
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
Documentation Common to Pack and Http Protocols
|
||||||
|
===============================================
|
||||||
|
|
||||||
|
ABNF Notation
|
||||||
|
-------------
|
||||||
|
|
||||||
|
ABNF notation as described by RFC 5234 is used within the protocol documents,
|
||||||
|
except the following replacement core rules are used:
|
||||||
|
----
|
||||||
|
HEXDIG = DIGIT / "a" / "b" / "c" / "d" / "e" / "f"
|
||||||
|
----
|
||||||
|
|
||||||
|
We also define the following common rules:
|
||||||
|
----
|
||||||
|
NUL = %x00
|
||||||
|
zero-id = 40*"0"
|
||||||
|
obj-id = 40*(HEXDIGIT)
|
||||||
|
|
||||||
|
refname = "HEAD"
|
||||||
|
refname /= "refs/" <see discussion below>
|
||||||
|
----
|
||||||
|
|
||||||
|
A refname is a hierarchical octet string beginning with "refs/" and
|
||||||
|
not violating the 'git-check-ref-format' command's validation rules.
|
||||||
|
More specifically, they:
|
||||||
|
|
||||||
|
. They can include slash `/` for hierarchical (directory)
|
||||||
|
grouping, but no slash-separated component can begin with a
|
||||||
|
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.
|
||||||
|
|
||||||
|
. 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}`, colon `:`, question-mark `?`, asterisk `*`,
|
||||||
|
or open bracket `[` anywhere.
|
||||||
|
|
||||||
|
. They cannot end with a slash `/` nor a dot `.`.
|
||||||
|
|
||||||
|
. They cannot end with the sequence `.lock`.
|
||||||
|
|
||||||
|
. They cannot contain a sequence `@{`.
|
||||||
|
|
||||||
|
. They cannot contain a `\\`.
|
||||||
|
|
||||||
|
|
||||||
|
pkt-line Format
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Much (but not all) of the payload is described around pkt-lines.
|
||||||
|
|
||||||
|
A pkt-line is a variable length binary string. The first four bytes
|
||||||
|
of the line, the pkt-len, indicates the total length of the line,
|
||||||
|
in hexadecimal. The pkt-len includes the 4 bytes used to contain
|
||||||
|
the length's hexadecimal representation.
|
||||||
|
|
||||||
|
A pkt-line MAY contain binary data, so implementors MUST ensure
|
||||||
|
pkt-line parsing/formatting routines are 8-bit clean.
|
||||||
|
|
||||||
|
A non-binary line SHOULD BE terminated by an LF, which if present
|
||||||
|
MUST be included in the total length.
|
||||||
|
|
||||||
|
The maximum length of a pkt-line's data component is 65520 bytes.
|
||||||
|
Implementations MUST NOT send pkt-line whose length exceeds 65524
|
||||||
|
(65520 bytes of payload + 4 bytes of length data).
|
||||||
|
|
||||||
|
Implementations SHOULD NOT send an empty pkt-line ("0004").
|
||||||
|
|
||||||
|
A pkt-line with a length field of 0 ("0000"), called a flush-pkt,
|
||||||
|
is a special case and MUST be handled differently than an empty
|
||||||
|
pkt-line ("0004").
|
||||||
|
|
||||||
|
----
|
||||||
|
pkt-line = data-pkt / flush-pkt
|
||||||
|
|
||||||
|
data-pkt = pkt-len pkt-payload
|
||||||
|
pkt-len = 4*(HEXDIG)
|
||||||
|
pkt-payload = (pkt-len - 4)*(OCTET)
|
||||||
|
|
||||||
|
flush-pkt = "0000"
|
||||||
|
----
|
||||||
|
|
||||||
|
Examples (as C-style strings):
|
||||||
|
|
||||||
|
----
|
||||||
|
pkt-line actual value
|
||||||
|
---------------------------------
|
||||||
|
"0006a\n" "a\n"
|
||||||
|
"0005a" "a"
|
||||||
|
"000bfoobar\n" "foobar\n"
|
||||||
|
"0004" ""
|
||||||
|
----
|
@ -1183,7 +1183,23 @@ $ git merge branchname
|
|||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
|
|
||||||
merges the development in the branch "branchname" into the current
|
merges the development in the branch "branchname" into the current
|
||||||
branch. If there are conflicts--for example, if the same file is
|
branch.
|
||||||
|
|
||||||
|
A merge is made by combining the changes made in "branchname" and the
|
||||||
|
changes made up to the latest commit in your current branch since
|
||||||
|
their histories forked. The work tree is overwritten by the result of
|
||||||
|
the merge when this combining is done cleanly, or overwritten by a
|
||||||
|
half-merged results when this combining results in conflicts.
|
||||||
|
Therefore, if you have uncommitted changes touching the same files as
|
||||||
|
the ones impacted by the merge, Git will refuse to proceed. Most of
|
||||||
|
the time, you will want to commit your changes before you can merge,
|
||||||
|
and if you don't, then linkgit:git-stash[1] can take these changes
|
||||||
|
away while you're doing the merge, and reapply them afterwards.
|
||||||
|
|
||||||
|
If the changes are independant enough, Git will automatically complete
|
||||||
|
the merge and commit the result (or reuse an existing commit in case
|
||||||
|
of <<fast-forwards,fast-forward>>, see below). On the other hand,
|
||||||
|
if there are conflicts--for example, if the same file is
|
||||||
modified in two different ways in the remote branch and the local
|
modified in two different ways in the remote branch and the local
|
||||||
branch--then you are warned; the output may look something like this:
|
branch--then you are warned; the output may look something like this:
|
||||||
|
|
||||||
@ -1384,7 +1400,7 @@ were merged.
|
|||||||
|
|
||||||
However, if the current branch is a descendant of the other--so every
|
However, if the current branch is a descendant of the other--so every
|
||||||
commit present in the one is already contained in the other--then git
|
commit present in the one is already contained in the other--then git
|
||||||
just performs a "fast forward"; the head of the current branch is moved
|
just performs a "fast-forward"; the head of the current branch is moved
|
||||||
forward to point at the head of the merged-in branch, without any new
|
forward to point at the head of the merged-in branch, without any new
|
||||||
commits being created.
|
commits being created.
|
||||||
|
|
||||||
@ -1679,7 +1695,7 @@ Sharing development with others
|
|||||||
Getting updates with git pull
|
Getting updates with git pull
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
After you clone a repository and make a few changes of your own, you
|
After you clone a repository and commit a few changes of your own, you
|
||||||
may wish to check the original repository for updates and merge them
|
may wish to check the original repository for updates and merge them
|
||||||
into your own work.
|
into your own work.
|
||||||
|
|
||||||
@ -1719,7 +1735,7 @@ producing a default commit message documenting the branch and
|
|||||||
repository that you pulled from.
|
repository that you pulled from.
|
||||||
|
|
||||||
(But note that no such commit will be created in the case of a
|
(But note that no such commit will be created in the case of a
|
||||||
<<fast-forwards,fast forward>>; instead, your branch will just be
|
<<fast-forwards,fast-forward>>; instead, your branch will just be
|
||||||
updated to point to the latest commit from the upstream branch.)
|
updated to point to the latest commit from the upstream branch.)
|
||||||
|
|
||||||
The `git pull` command can also be given "." as the "remote" repository,
|
The `git pull` command can also be given "." as the "remote" repository,
|
||||||
@ -1943,7 +1959,7 @@ $ git push ssh://yourserver.com/~you/proj.git master
|
|||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
|
|
||||||
As with `git fetch`, `git push` will complain if this does not result in a
|
As with `git fetch`, `git push` will complain if this does not result in a
|
||||||
<<fast-forwards,fast forward>>; see the following section for details on
|
<<fast-forwards,fast-forward>>; see the following section for details on
|
||||||
handling this case.
|
handling this case.
|
||||||
|
|
||||||
Note that the target of a "push" is normally a
|
Note that the target of a "push" is normally a
|
||||||
@ -1976,7 +1992,7 @@ details.
|
|||||||
What to do when a push fails
|
What to do when a push fails
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
If a push would not result in a <<fast-forwards,fast forward>> of the
|
If a push would not result in a <<fast-forwards,fast-forward>> of the
|
||||||
remote branch, then it will fail with an error like:
|
remote branch, then it will fail with an error like:
|
||||||
|
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
@ -2115,7 +2131,7 @@ $ git checkout release && git pull
|
|||||||
|
|
||||||
Important note! If you have any local changes in these branches, then
|
Important note! If you have any local changes in these branches, then
|
||||||
this merge will create a commit object in the history (with no local
|
this merge will create a commit object in the history (with no local
|
||||||
changes git will simply do a "Fast forward" merge). Many people dislike
|
changes git will simply do a "fast-forward" merge). Many people dislike
|
||||||
the "noise" that this creates in the Linux history, so you should avoid
|
the "noise" that this creates in the Linux history, so you should avoid
|
||||||
doing this capriciously in the "release" branch, as these noisy commits
|
doing this capriciously in the "release" branch, as these noisy commits
|
||||||
will become part of the permanent history when you ask Linus to pull
|
will become part of the permanent history when you ask Linus to pull
|
||||||
@ -2569,7 +2585,7 @@ them again with linkgit:git-am[1].
|
|||||||
Other tools
|
Other tools
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
There are numerous other tools, such as StGIT, which exist for the
|
There are numerous other tools, such as StGit, which exist for the
|
||||||
purpose of maintaining a patch series. These are outside of the scope of
|
purpose of maintaining a patch series. These are outside of the scope of
|
||||||
this manual.
|
this manual.
|
||||||
|
|
||||||
@ -2729,9 +2745,9 @@ In the previous example, when updating an existing branch, "git fetch"
|
|||||||
checks to make sure that the most recent commit on the remote
|
checks to make sure that the most recent commit on the remote
|
||||||
branch is a descendant of the most recent commit on your copy of the
|
branch is a descendant of the most recent commit on your copy of the
|
||||||
branch before updating your copy of the branch to point at the new
|
branch before updating your copy of the branch to point at the new
|
||||||
commit. Git calls this process a <<fast-forwards,fast forward>>.
|
commit. Git calls this process a <<fast-forwards,fast-forward>>.
|
||||||
|
|
||||||
A fast forward looks something like this:
|
A fast-forward looks something like this:
|
||||||
|
|
||||||
................................................
|
................................................
|
||||||
o--o--o--o <-- old head of the branch
|
o--o--o--o <-- old head of the branch
|
||||||
@ -4275,7 +4291,7 @@ You see, Git is actually the best tool to find out about the source of Git
|
|||||||
itself!
|
itself!
|
||||||
|
|
||||||
[[glossary]]
|
[[glossary]]
|
||||||
GIT Glossary
|
Git Glossary
|
||||||
============
|
============
|
||||||
|
|
||||||
include::glossary-content.txt[]
|
include::glossary-content.txt[]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
GVF=GIT-VERSION-FILE
|
GVF=GIT-VERSION-FILE
|
||||||
DEF_VER=v1.6.5
|
DEF_VER=v1.6.5.GIT
|
||||||
|
|
||||||
LF='
|
LF='
|
||||||
'
|
'
|
||||||
|
77
Makefile
77
Makefile
@ -159,6 +159,10 @@ all::
|
|||||||
# Define ASCIIDOC_NO_ROFF if your DocBook XSL escapes raw roff directives
|
# Define ASCIIDOC_NO_ROFF if your DocBook XSL escapes raw roff directives
|
||||||
# (versions 1.72 and later and 1.68.1 and earlier).
|
# (versions 1.72 and later and 1.68.1 and earlier).
|
||||||
#
|
#
|
||||||
|
# Define GNU_ROFF if your target system uses GNU groff. This forces
|
||||||
|
# apostrophes to be ASCII so that cut&pasting examples to the shell
|
||||||
|
# will work.
|
||||||
|
#
|
||||||
# Define NO_PERL_MAKEMAKER if you cannot use Makefiles generated by perl's
|
# Define NO_PERL_MAKEMAKER if you cannot use Makefiles generated by perl's
|
||||||
# MakeMaker (e.g. using ActiveState under Cygwin).
|
# MakeMaker (e.g. using ActiveState under Cygwin).
|
||||||
#
|
#
|
||||||
@ -200,6 +204,18 @@ all::
|
|||||||
# memory allocators with the nedmalloc allocator written by Niall Douglas.
|
# memory allocators with the nedmalloc allocator written by Niall Douglas.
|
||||||
#
|
#
|
||||||
# Define NO_REGEX if you have no or inferior regex support in your C library.
|
# Define NO_REGEX if you have no or inferior regex support in your C library.
|
||||||
|
#
|
||||||
|
# Define DEFAULT_PAGER to a sensible pager command (defaults to "less") if
|
||||||
|
# you want to use something different. The value will be interpreted by the
|
||||||
|
# shell at runtime when it is used.
|
||||||
|
#
|
||||||
|
# Define DEFAULT_EDITOR to a sensible editor command (defaults to "vi") if you
|
||||||
|
# want to use something different. The value will be interpreted by the shell
|
||||||
|
# if necessary when it is used. Examples:
|
||||||
|
#
|
||||||
|
# DEFAULT_EDITOR='~/bin/vi',
|
||||||
|
# DEFAULT_EDITOR='$GIT_FALLBACK_EDITOR',
|
||||||
|
# DEFAULT_EDITOR='"C:\Program Files\Vim\gvim.exe" --nofork'
|
||||||
|
|
||||||
GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
|
GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
|
||||||
@$(SHELL_PATH) ./GIT-VERSION-GEN
|
@$(SHELL_PATH) ./GIT-VERSION-GEN
|
||||||
@ -212,6 +228,12 @@ uname_R := $(shell sh -c 'uname -r 2>/dev/null || echo not')
|
|||||||
uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not')
|
uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not')
|
||||||
uname_V := $(shell sh -c 'uname -v 2>/dev/null || echo not')
|
uname_V := $(shell sh -c 'uname -v 2>/dev/null || echo not')
|
||||||
|
|
||||||
|
ifdef MSVC
|
||||||
|
# avoid the MingW and Cygwin configuration sections
|
||||||
|
uname_S := Windows
|
||||||
|
uname_O := Windows
|
||||||
|
endif
|
||||||
|
|
||||||
# CFLAGS and LDFLAGS are for the users to override from the command line.
|
# CFLAGS and LDFLAGS are for the users to override from the command line.
|
||||||
|
|
||||||
CFLAGS = -g -O2 -Wall
|
CFLAGS = -g -O2 -Wall
|
||||||
@ -321,6 +343,7 @@ SCRIPT_SH += git-merge-one-file.sh
|
|||||||
SCRIPT_SH += git-merge-resolve.sh
|
SCRIPT_SH += git-merge-resolve.sh
|
||||||
SCRIPT_SH += git-mergetool.sh
|
SCRIPT_SH += git-mergetool.sh
|
||||||
SCRIPT_SH += git-mergetool--lib.sh
|
SCRIPT_SH += git-mergetool--lib.sh
|
||||||
|
SCRIPT_SH += git-notes.sh
|
||||||
SCRIPT_SH += git-parse-remote.sh
|
SCRIPT_SH += git-parse-remote.sh
|
||||||
SCRIPT_SH += git-pull.sh
|
SCRIPT_SH += git-pull.sh
|
||||||
SCRIPT_SH += git-quiltimport.sh
|
SCRIPT_SH += git-quiltimport.sh
|
||||||
@ -354,6 +377,7 @@ EXTRA_PROGRAMS =
|
|||||||
PROGRAMS += $(EXTRA_PROGRAMS)
|
PROGRAMS += $(EXTRA_PROGRAMS)
|
||||||
PROGRAMS += git-fast-import$X
|
PROGRAMS += git-fast-import$X
|
||||||
PROGRAMS += git-hash-object$X
|
PROGRAMS += git-hash-object$X
|
||||||
|
PROGRAMS += git-imap-send$X
|
||||||
PROGRAMS += git-index-pack$X
|
PROGRAMS += git-index-pack$X
|
||||||
PROGRAMS += git-merge-index$X
|
PROGRAMS += git-merge-index$X
|
||||||
PROGRAMS += git-merge-tree$X
|
PROGRAMS += git-merge-tree$X
|
||||||
@ -365,6 +389,7 @@ PROGRAMS += git-show-index$X
|
|||||||
PROGRAMS += git-unpack-file$X
|
PROGRAMS += git-unpack-file$X
|
||||||
PROGRAMS += git-upload-pack$X
|
PROGRAMS += git-upload-pack$X
|
||||||
PROGRAMS += git-var$X
|
PROGRAMS += git-var$X
|
||||||
|
PROGRAMS += git-http-backend$X
|
||||||
|
|
||||||
# List built-in command $C whose implementation cmd_$C() is not in
|
# List built-in command $C whose implementation cmd_$C() is not in
|
||||||
# builtin-$C.o but is linked in as part of some other command.
|
# builtin-$C.o but is linked in as part of some other command.
|
||||||
@ -412,6 +437,7 @@ LIB_H += builtin.h
|
|||||||
LIB_H += cache.h
|
LIB_H += cache.h
|
||||||
LIB_H += cache-tree.h
|
LIB_H += cache-tree.h
|
||||||
LIB_H += commit.h
|
LIB_H += commit.h
|
||||||
|
LIB_H += compat/bswap.h
|
||||||
LIB_H += compat/cygwin.h
|
LIB_H += compat/cygwin.h
|
||||||
LIB_H += compat/mingw.h
|
LIB_H += compat/mingw.h
|
||||||
LIB_H += csum-file.h
|
LIB_H += csum-file.h
|
||||||
@ -432,6 +458,7 @@ LIB_H += ll-merge.h
|
|||||||
LIB_H += log-tree.h
|
LIB_H += log-tree.h
|
||||||
LIB_H += mailmap.h
|
LIB_H += mailmap.h
|
||||||
LIB_H += merge-recursive.h
|
LIB_H += merge-recursive.h
|
||||||
|
LIB_H += notes.h
|
||||||
LIB_H += object.h
|
LIB_H += object.h
|
||||||
LIB_H += pack.h
|
LIB_H += pack.h
|
||||||
LIB_H += pack-refs.h
|
LIB_H += pack-refs.h
|
||||||
@ -452,6 +479,7 @@ LIB_H += sideband.h
|
|||||||
LIB_H += sigchain.h
|
LIB_H += sigchain.h
|
||||||
LIB_H += strbuf.h
|
LIB_H += strbuf.h
|
||||||
LIB_H += string-list.h
|
LIB_H += string-list.h
|
||||||
|
LIB_H += submodule.h
|
||||||
LIB_H += tag.h
|
LIB_H += tag.h
|
||||||
LIB_H += transport.h
|
LIB_H += transport.h
|
||||||
LIB_H += tree.h
|
LIB_H += tree.h
|
||||||
@ -516,6 +544,7 @@ LIB_OBJS += match-trees.o
|
|||||||
LIB_OBJS += merge-file.o
|
LIB_OBJS += merge-file.o
|
||||||
LIB_OBJS += merge-recursive.o
|
LIB_OBJS += merge-recursive.o
|
||||||
LIB_OBJS += name-hash.o
|
LIB_OBJS += name-hash.o
|
||||||
|
LIB_OBJS += notes.o
|
||||||
LIB_OBJS += object.o
|
LIB_OBJS += object.o
|
||||||
LIB_OBJS += pack-check.o
|
LIB_OBJS += pack-check.o
|
||||||
LIB_OBJS += pack-refs.o
|
LIB_OBJS += pack-refs.o
|
||||||
@ -550,6 +579,7 @@ LIB_OBJS += sideband.o
|
|||||||
LIB_OBJS += sigchain.o
|
LIB_OBJS += sigchain.o
|
||||||
LIB_OBJS += strbuf.o
|
LIB_OBJS += strbuf.o
|
||||||
LIB_OBJS += string-list.o
|
LIB_OBJS += string-list.o
|
||||||
|
LIB_OBJS += submodule.o
|
||||||
LIB_OBJS += symlinks.o
|
LIB_OBJS += symlinks.o
|
||||||
LIB_OBJS += tag.o
|
LIB_OBJS += tag.o
|
||||||
LIB_OBJS += trace.o
|
LIB_OBJS += trace.o
|
||||||
@ -594,7 +624,6 @@ BUILTIN_OBJS += builtin-diff-index.o
|
|||||||
BUILTIN_OBJS += builtin-diff-tree.o
|
BUILTIN_OBJS += builtin-diff-tree.o
|
||||||
BUILTIN_OBJS += builtin-diff.o
|
BUILTIN_OBJS += builtin-diff.o
|
||||||
BUILTIN_OBJS += builtin-fast-export.o
|
BUILTIN_OBJS += builtin-fast-export.o
|
||||||
BUILTIN_OBJS += builtin-fetch--tool.o
|
|
||||||
BUILTIN_OBJS += builtin-fetch-pack.o
|
BUILTIN_OBJS += builtin-fetch-pack.o
|
||||||
BUILTIN_OBJS += builtin-fetch.o
|
BUILTIN_OBJS += builtin-fetch.o
|
||||||
BUILTIN_OBJS += builtin-fmt-merge-msg.o
|
BUILTIN_OBJS += builtin-fmt-merge-msg.o
|
||||||
@ -776,12 +805,15 @@ ifeq ($(uname_O),Cygwin)
|
|||||||
NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes
|
NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes
|
||||||
NO_TRUSTABLE_FILEMODE = UnfortunatelyYes
|
NO_TRUSTABLE_FILEMODE = UnfortunatelyYes
|
||||||
OLD_ICONV = UnfortunatelyYes
|
OLD_ICONV = UnfortunatelyYes
|
||||||
|
NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
|
||||||
# There are conflicting reports about this.
|
# There are conflicting reports about this.
|
||||||
# On some boxes NO_MMAP is needed, and not so elsewhere.
|
# On some boxes NO_MMAP is needed, and not so elsewhere.
|
||||||
# Try commenting this out if you suspect MMAP is more efficient
|
# Try commenting this out if you suspect MMAP is more efficient
|
||||||
NO_MMAP = YesPlease
|
NO_MMAP = YesPlease
|
||||||
NO_IPV6 = YesPlease
|
NO_IPV6 = YesPlease
|
||||||
X = .exe
|
X = .exe
|
||||||
|
COMPAT_OBJS += compat/cygwin.o
|
||||||
|
UNRELIABLE_FSTAT = UnfortunatelyYes
|
||||||
endif
|
endif
|
||||||
ifeq ($(uname_S),FreeBSD)
|
ifeq ($(uname_S),FreeBSD)
|
||||||
NEEDS_LIBICONV = YesPlease
|
NEEDS_LIBICONV = YesPlease
|
||||||
@ -891,15 +923,11 @@ ifeq ($(uname_S),HP-UX)
|
|||||||
NO_SYS_SELECT_H = YesPlease
|
NO_SYS_SELECT_H = YesPlease
|
||||||
SNPRINTF_RETURNS_BOGUS = YesPlease
|
SNPRINTF_RETURNS_BOGUS = YesPlease
|
||||||
endif
|
endif
|
||||||
ifneq (,$(findstring CYGWIN,$(uname_S)))
|
ifeq ($(uname_S),Windows)
|
||||||
COMPAT_OBJS += compat/cygwin.o
|
|
||||||
UNRELIABLE_FSTAT = UnfortunatelyYes
|
|
||||||
endif
|
|
||||||
ifdef MSVC
|
|
||||||
GIT_VERSION := $(GIT_VERSION).MSVC
|
GIT_VERSION := $(GIT_VERSION).MSVC
|
||||||
pathsep = ;
|
pathsep = ;
|
||||||
NO_PREAD = YesPlease
|
NO_PREAD = YesPlease
|
||||||
NO_OPENSSL = YesPlease
|
NEEDS_CRYPTO_WITH_SSL = YesPlease
|
||||||
NO_LIBGEN_H = YesPlease
|
NO_LIBGEN_H = YesPlease
|
||||||
NO_SYMLINK_HEAD = YesPlease
|
NO_SYMLINK_HEAD = YesPlease
|
||||||
NO_IPV6 = YesPlease
|
NO_IPV6 = YesPlease
|
||||||
@ -929,6 +957,7 @@ ifdef MSVC
|
|||||||
NO_REGEX = YesPlease
|
NO_REGEX = YesPlease
|
||||||
NO_CURL = YesPlease
|
NO_CURL = YesPlease
|
||||||
NO_PTHREADS = YesPlease
|
NO_PTHREADS = YesPlease
|
||||||
|
BLK_SHA1 = YesPlease
|
||||||
|
|
||||||
CC = compat/vcbuild/scripts/clink.pl
|
CC = compat/vcbuild/scripts/clink.pl
|
||||||
AR = compat/vcbuild/scripts/lib.pl
|
AR = compat/vcbuild/scripts/lib.pl
|
||||||
@ -947,14 +976,13 @@ else
|
|||||||
BASIC_CFLAGS += -Zi -MTd
|
BASIC_CFLAGS += -Zi -MTd
|
||||||
endif
|
endif
|
||||||
X = .exe
|
X = .exe
|
||||||
else
|
endif
|
||||||
ifneq (,$(findstring MINGW,$(uname_S)))
|
ifneq (,$(findstring MINGW,$(uname_S)))
|
||||||
pathsep = ;
|
pathsep = ;
|
||||||
NO_PREAD = YesPlease
|
NO_PREAD = YesPlease
|
||||||
NO_OPENSSL = YesPlease
|
NEEDS_CRYPTO_WITH_SSL = YesPlease
|
||||||
NO_LIBGEN_H = YesPlease
|
NO_LIBGEN_H = YesPlease
|
||||||
NO_SYMLINK_HEAD = YesPlease
|
NO_SYMLINK_HEAD = YesPlease
|
||||||
NO_IPV6 = YesPlease
|
|
||||||
NO_SETENV = YesPlease
|
NO_SETENV = YesPlease
|
||||||
NO_UNSETENV = YesPlease
|
NO_UNSETENV = YesPlease
|
||||||
NO_STRCASESTR = YesPlease
|
NO_STRCASESTR = YesPlease
|
||||||
@ -978,6 +1006,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
|
|||||||
UNRELIABLE_FSTAT = UnfortunatelyYes
|
UNRELIABLE_FSTAT = UnfortunatelyYes
|
||||||
OBJECT_CREATION_USES_RENAMES = UnfortunatelyNeedsTo
|
OBJECT_CREATION_USES_RENAMES = UnfortunatelyNeedsTo
|
||||||
NO_REGEX = YesPlease
|
NO_REGEX = YesPlease
|
||||||
|
BLK_SHA1 = YesPlease
|
||||||
COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch
|
COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch
|
||||||
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
|
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
|
||||||
COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o
|
COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o
|
||||||
@ -996,7 +1025,6 @@ else
|
|||||||
NO_PTHREADS = YesPlease
|
NO_PTHREADS = YesPlease
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
|
||||||
|
|
||||||
-include config.mak.autogen
|
-include config.mak.autogen
|
||||||
-include config.mak
|
-include config.mak
|
||||||
@ -1075,7 +1103,6 @@ EXTLIBS += -lz
|
|||||||
|
|
||||||
ifndef NO_POSIX_ONLY_PROGRAMS
|
ifndef NO_POSIX_ONLY_PROGRAMS
|
||||||
PROGRAMS += git-daemon$X
|
PROGRAMS += git-daemon$X
|
||||||
PROGRAMS += git-imap-send$X
|
|
||||||
endif
|
endif
|
||||||
ifndef NO_OPENSSL
|
ifndef NO_OPENSSL
|
||||||
OPENSSL_LIBSSL = -lssl
|
OPENSSL_LIBSSL = -lssl
|
||||||
@ -1363,6 +1390,22 @@ BASIC_CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER_SQ)' \
|
|||||||
$(COMPAT_CFLAGS)
|
$(COMPAT_CFLAGS)
|
||||||
LIB_OBJS += $(COMPAT_OBJS)
|
LIB_OBJS += $(COMPAT_OBJS)
|
||||||
|
|
||||||
|
# Quote for C
|
||||||
|
|
||||||
|
ifdef DEFAULT_EDITOR
|
||||||
|
DEFAULT_EDITOR_CQ = "$(subst ",\",$(subst \,\\,$(DEFAULT_EDITOR)))"
|
||||||
|
DEFAULT_EDITOR_CQ_SQ = $(subst ','\'',$(DEFAULT_EDITOR_CQ))
|
||||||
|
|
||||||
|
BASIC_CFLAGS += -DDEFAULT_EDITOR='$(DEFAULT_EDITOR_CQ_SQ)'
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef DEFAULT_PAGER
|
||||||
|
DEFAULT_PAGER_CQ = "$(subst ",\",$(subst \,\\,$(DEFAULT_PAGER)))"
|
||||||
|
DEFAULT_PAGER_CQ_SQ = $(subst ','\'',$(DEFAULT_PAGER_CQ))
|
||||||
|
|
||||||
|
BASIC_CFLAGS += -DDEFAULT_PAGER='$(DEFAULT_PAGER_CQ_SQ)'
|
||||||
|
endif
|
||||||
|
|
||||||
ALL_CFLAGS += $(BASIC_CFLAGS)
|
ALL_CFLAGS += $(BASIC_CFLAGS)
|
||||||
ALL_LDFLAGS += $(BASIC_LDFLAGS)
|
ALL_LDFLAGS += $(BASIC_LDFLAGS)
|
||||||
|
|
||||||
@ -1375,7 +1418,7 @@ SHELL = $(SHELL_PATH)
|
|||||||
|
|
||||||
all:: shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS
|
all:: shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS
|
||||||
ifneq (,$X)
|
ifneq (,$X)
|
||||||
$(QUIET_BUILT_IN)$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), test '$p' -ef '$p$X' || $(RM) '$p';)
|
$(QUIET_BUILT_IN)$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), test -d '$p' -o '$p' -ef '$p$X' || $(RM) '$p';)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
all::
|
all::
|
||||||
@ -1626,6 +1669,7 @@ GIT-CFLAGS: .FORCE-GIT-CFLAGS
|
|||||||
# and the first level quoting from the shell that runs "echo".
|
# and the first level quoting from the shell that runs "echo".
|
||||||
GIT-BUILD-OPTIONS: .FORCE-GIT-BUILD-OPTIONS
|
GIT-BUILD-OPTIONS: .FORCE-GIT-BUILD-OPTIONS
|
||||||
@echo SHELL_PATH=\''$(subst ','\'',$(SHELL_PATH_SQ))'\' >$@
|
@echo SHELL_PATH=\''$(subst ','\'',$(SHELL_PATH_SQ))'\' >$@
|
||||||
|
@echo PERL_PATH=\''$(subst ','\'',$(PERL_PATH_SQ))'\' >>$@
|
||||||
@echo TAR=\''$(subst ','\'',$(subst ','\'',$(TAR)))'\' >>$@
|
@echo TAR=\''$(subst ','\'',$(subst ','\'',$(TAR)))'\' >>$@
|
||||||
@echo NO_CURL=\''$(subst ','\'',$(subst ','\'',$(NO_CURL)))'\' >>$@
|
@echo NO_CURL=\''$(subst ','\'',$(subst ','\'',$(NO_CURL)))'\' >>$@
|
||||||
@echo NO_PERL=\''$(subst ','\'',$(subst ','\'',$(NO_PERL)))'\' >>$@
|
@echo NO_PERL=\''$(subst ','\'',$(subst ','\'',$(NO_PERL)))'\' >>$@
|
||||||
@ -1799,7 +1843,10 @@ dist: git.spec git-archive$(X) configure
|
|||||||
gzip -f -9 $(GIT_TARNAME).tar
|
gzip -f -9 $(GIT_TARNAME).tar
|
||||||
|
|
||||||
rpm: dist
|
rpm: dist
|
||||||
$(RPMBUILD) -ta $(GIT_TARNAME).tar.gz
|
$(RPMBUILD) \
|
||||||
|
--define "_source_filedigest_algorithm md5" \
|
||||||
|
--define "_binary_filedigest_algorithm md5" \
|
||||||
|
-ta $(GIT_TARNAME).tar.gz
|
||||||
|
|
||||||
htmldocs = git-htmldocs-$(GIT_VERSION)
|
htmldocs = git-htmldocs-$(GIT_VERSION)
|
||||||
manpages = git-manpages-$(GIT_VERSION)
|
manpages = git-manpages-$(GIT_VERSION)
|
||||||
@ -1827,7 +1874,7 @@ distclean: clean
|
|||||||
$(RM) configure
|
$(RM) configure
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) *.o mozilla-sha1/*.o arm/*.o ppc/*.o compat/*.o compat/*/*.o xdiff/*.o \
|
$(RM) *.o block-sha1/*.o ppc/*.o compat/*.o compat/*/*.o xdiff/*.o \
|
||||||
$(LIB_FILE) $(XDIFF_LIB)
|
$(LIB_FILE) $(XDIFF_LIB)
|
||||||
$(RM) $(ALL_PROGRAMS) $(BUILT_INS) git$X
|
$(RM) $(ALL_PROGRAMS) $(BUILT_INS) git$X
|
||||||
$(RM) $(TEST_PROGRAMS)
|
$(RM) $(TEST_PROGRAMS)
|
||||||
|
2
advice.c
2
advice.c
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
int advice_push_nonfastforward = 1;
|
int advice_push_nonfastforward = 1;
|
||||||
int advice_status_hints = 1;
|
int advice_status_hints = 1;
|
||||||
|
int advice_commit_before_merge = 1;
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -9,6 +10,7 @@ static struct {
|
|||||||
} advice_config[] = {
|
} advice_config[] = {
|
||||||
{ "pushnonfastforward", &advice_push_nonfastforward },
|
{ "pushnonfastforward", &advice_push_nonfastforward },
|
||||||
{ "statushints", &advice_status_hints },
|
{ "statushints", &advice_status_hints },
|
||||||
|
{ "commitbeforemerge", &advice_commit_before_merge },
|
||||||
};
|
};
|
||||||
|
|
||||||
int git_default_advice_config(const char *var, const char *value)
|
int git_default_advice_config(const char *var, const char *value)
|
||||||
|
1
advice.h
1
advice.h
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
extern int advice_push_nonfastforward;
|
extern int advice_push_nonfastforward;
|
||||||
extern int advice_status_hints;
|
extern int advice_status_hints;
|
||||||
|
extern int advice_commit_before_merge;
|
||||||
|
|
||||||
int git_default_advice_config(const char *var, const char *value);
|
int git_default_advice_config(const char *var, const char *value);
|
||||||
|
|
||||||
|
@ -31,6 +31,8 @@ static void format_subst(const struct commit *commit,
|
|||||||
{
|
{
|
||||||
char *to_free = NULL;
|
char *to_free = NULL;
|
||||||
struct strbuf fmt = STRBUF_INIT;
|
struct strbuf fmt = STRBUF_INIT;
|
||||||
|
struct pretty_print_context ctx = {0};
|
||||||
|
ctx.date_mode = DATE_NORMAL;
|
||||||
|
|
||||||
if (src == buf->buf)
|
if (src == buf->buf)
|
||||||
to_free = strbuf_detach(buf, NULL);
|
to_free = strbuf_detach(buf, NULL);
|
||||||
@ -48,7 +50,7 @@ static void format_subst(const struct commit *commit,
|
|||||||
strbuf_add(&fmt, b + 8, c - b - 8);
|
strbuf_add(&fmt, b + 8, c - b - 8);
|
||||||
|
|
||||||
strbuf_add(buf, src, b - src);
|
strbuf_add(buf, src, b - src);
|
||||||
format_commit_message(commit, fmt.buf, buf, DATE_NORMAL);
|
format_commit_message(commit, fmt.buf, buf, &ctx);
|
||||||
len -= c + 1 - src;
|
len -= c + 1 - src;
|
||||||
src = c + 1;
|
src = c + 1;
|
||||||
}
|
}
|
||||||
|
@ -153,6 +153,7 @@ struct fragment {
|
|||||||
const char *patch;
|
const char *patch;
|
||||||
int size;
|
int size;
|
||||||
int rejected;
|
int rejected;
|
||||||
|
int linenr;
|
||||||
struct fragment *next;
|
struct fragment *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -822,12 +823,13 @@ static int gitdiff_unrecognized(const char *line, struct patch *patch)
|
|||||||
|
|
||||||
static const char *stop_at_slash(const char *line, int llen)
|
static const char *stop_at_slash(const char *line, int llen)
|
||||||
{
|
{
|
||||||
|
int nslash = p_value;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < llen; i++) {
|
for (i = 0; i < llen; i++) {
|
||||||
int ch = line[i];
|
int ch = line[i];
|
||||||
if (ch == '/')
|
if (ch == '/' && --nslash <= 0)
|
||||||
return line + i;
|
return &line[i];
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1227,23 +1229,29 @@ static int find_header(char *line, unsigned long size, int *hdrsize, struct patc
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_whitespace(const char *line, int len, unsigned ws_rule)
|
static void record_ws_error(unsigned result, const char *line, int len, int linenr)
|
||||||
{
|
{
|
||||||
char *err;
|
char *err;
|
||||||
unsigned result = ws_check(line + 1, len - 1, ws_rule);
|
|
||||||
if (!result)
|
if (!result)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
whitespace_error++;
|
whitespace_error++;
|
||||||
if (squelch_whitespace_errors &&
|
if (squelch_whitespace_errors &&
|
||||||
squelch_whitespace_errors < whitespace_error)
|
squelch_whitespace_errors < whitespace_error)
|
||||||
;
|
return;
|
||||||
else {
|
|
||||||
err = whitespace_error_string(result);
|
err = whitespace_error_string(result);
|
||||||
fprintf(stderr, "%s:%d: %s.\n%.*s\n",
|
fprintf(stderr, "%s:%d: %s.\n%.*s\n",
|
||||||
patch_input_file, linenr, err, len - 2, line + 1);
|
patch_input_file, linenr, err, len, line);
|
||||||
free(err);
|
free(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void check_whitespace(const char *line, int len, unsigned ws_rule)
|
||||||
|
{
|
||||||
|
unsigned result = ws_check(line + 1, len - 1, ws_rule);
|
||||||
|
|
||||||
|
record_ws_error(result, line + 1, len - 2, linenr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1359,6 +1367,7 @@ static int parse_single_patch(char *line, unsigned long size, struct patch *patc
|
|||||||
int len;
|
int len;
|
||||||
|
|
||||||
fragment = xcalloc(1, sizeof(*fragment));
|
fragment = xcalloc(1, sizeof(*fragment));
|
||||||
|
fragment->linenr = linenr;
|
||||||
len = parse_fragment(line, size, patch, fragment);
|
len = parse_fragment(line, size, patch, fragment);
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
die("corrupt patch at line %d", linenr);
|
die("corrupt patch at line %d", linenr);
|
||||||
@ -2142,6 +2151,7 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
|
|||||||
int len = linelen(patch, size);
|
int len = linelen(patch, size);
|
||||||
int plen, added;
|
int plen, added;
|
||||||
int added_blank_line = 0;
|
int added_blank_line = 0;
|
||||||
|
int is_blank_context = 0;
|
||||||
|
|
||||||
if (!len)
|
if (!len)
|
||||||
break;
|
break;
|
||||||
@ -2174,8 +2184,12 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
|
|||||||
*new++ = '\n';
|
*new++ = '\n';
|
||||||
add_line_info(&preimage, "\n", 1, LINE_COMMON);
|
add_line_info(&preimage, "\n", 1, LINE_COMMON);
|
||||||
add_line_info(&postimage, "\n", 1, LINE_COMMON);
|
add_line_info(&postimage, "\n", 1, LINE_COMMON);
|
||||||
|
is_blank_context = 1;
|
||||||
break;
|
break;
|
||||||
case ' ':
|
case ' ':
|
||||||
|
if (plen && (ws_rule & WS_BLANK_AT_EOF) &&
|
||||||
|
ws_blank_line(patch + 1, plen, ws_rule))
|
||||||
|
is_blank_context = 1;
|
||||||
case '-':
|
case '-':
|
||||||
memcpy(old, patch + 1, plen);
|
memcpy(old, patch + 1, plen);
|
||||||
add_line_info(&preimage, old, plen,
|
add_line_info(&preimage, old, plen,
|
||||||
@ -2202,7 +2216,8 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
|
|||||||
(first == '+' ? 0 : LINE_COMMON));
|
(first == '+' ? 0 : LINE_COMMON));
|
||||||
new += added;
|
new += added;
|
||||||
if (first == '+' &&
|
if (first == '+' &&
|
||||||
added == 1 && new[-1] == '\n')
|
(ws_rule & WS_BLANK_AT_EOF) &&
|
||||||
|
ws_blank_line(patch + 1, plen, ws_rule))
|
||||||
added_blank_line = 1;
|
added_blank_line = 1;
|
||||||
break;
|
break;
|
||||||
case '@': case '\\':
|
case '@': case '\\':
|
||||||
@ -2215,6 +2230,8 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
|
|||||||
}
|
}
|
||||||
if (added_blank_line)
|
if (added_blank_line)
|
||||||
new_blank_lines_at_end++;
|
new_blank_lines_at_end++;
|
||||||
|
else if (is_blank_context)
|
||||||
|
;
|
||||||
else
|
else
|
||||||
new_blank_lines_at_end = 0;
|
new_blank_lines_at_end = 0;
|
||||||
patch += len;
|
patch += len;
|
||||||
@ -2296,18 +2313,25 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (applied_pos >= 0) {
|
if (applied_pos >= 0) {
|
||||||
if (ws_error_action == correct_ws_error &&
|
if (new_blank_lines_at_end &&
|
||||||
new_blank_lines_at_end &&
|
preimage.nr + applied_pos == img->nr &&
|
||||||
postimage.nr + applied_pos == img->nr) {
|
(ws_rule & WS_BLANK_AT_EOF) &&
|
||||||
/*
|
ws_error_action != nowarn_ws_error) {
|
||||||
* If the patch application adds blank lines
|
record_ws_error(WS_BLANK_AT_EOF, "+", 1, frag->linenr);
|
||||||
* at the end, and if the patch applies at the
|
if (ws_error_action == correct_ws_error) {
|
||||||
* end of the image, remove those added blank
|
|
||||||
* lines.
|
|
||||||
*/
|
|
||||||
while (new_blank_lines_at_end--)
|
while (new_blank_lines_at_end--)
|
||||||
remove_last_line(&postimage);
|
remove_last_line(&postimage);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* We would want to prevent write_out_results()
|
||||||
|
* from taking place in apply_patch() that follows
|
||||||
|
* the callchain led us here, which is:
|
||||||
|
* apply_patch->check_patch_list->check_patch->
|
||||||
|
* apply_data->apply_fragments->apply_one_fragment
|
||||||
|
*/
|
||||||
|
if (ws_error_action == die_on_ws_error)
|
||||||
|
apply = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Warn if it was necessary to reduce the number
|
* Warn if it was necessary to reduce the number
|
||||||
|
@ -1604,6 +1604,9 @@ static void emit_porcelain(struct scoreboard *sb, struct blame_entry *ent)
|
|||||||
} while (ch != '\n' &&
|
} while (ch != '\n' &&
|
||||||
cp < sb->final_buf + sb->final_buf_size);
|
cp < sb->final_buf + sb->final_buf_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sb->final_buf_size && cp[-1] != '\n')
|
||||||
|
putchar('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)
|
static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)
|
||||||
@ -1667,6 +1670,9 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)
|
|||||||
} while (ch != '\n' &&
|
} while (ch != '\n' &&
|
||||||
cp < sb->final_buf + sb->final_buf_size);
|
cp < sb->final_buf + sb->final_buf_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sb->final_buf_size && cp[-1] != '\n')
|
||||||
|
putchar('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
static void output(struct scoreboard *sb, int option)
|
static void output(struct scoreboard *sb, int option)
|
||||||
@ -2352,6 +2358,7 @@ parse_done:
|
|||||||
die_errno("cannot stat path '%s'", path);
|
die_errno("cannot stat path '%s'", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
revs.disable_stdin = 1;
|
||||||
setup_revisions(argc, argv, &revs, NULL);
|
setup_revisions(argc, argv, &revs, NULL);
|
||||||
memset(&sb, 0, sizeof(sb));
|
memset(&sb, 0, sizeof(sb));
|
||||||
|
|
||||||
|
@ -387,8 +387,9 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
|
|||||||
|
|
||||||
commit = item->commit;
|
commit = item->commit;
|
||||||
if (commit && !parse_commit(commit)) {
|
if (commit && !parse_commit(commit)) {
|
||||||
|
struct pretty_print_context ctx = {0};
|
||||||
pretty_print_commit(CMIT_FMT_ONELINE, commit,
|
pretty_print_commit(CMIT_FMT_ONELINE, commit,
|
||||||
&subject, 0, NULL, NULL, 0, 0);
|
&subject, &ctx);
|
||||||
sub = subject.buf;
|
sub = subject.buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,8 +7,37 @@
|
|||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
|
|
||||||
|
static const char builtin_check_ref_format_usage[] =
|
||||||
|
"git check-ref-format [--print] <refname>\n"
|
||||||
|
" or: git check-ref-format --branch <branchname-shorthand>";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 void collapse_slashes(char *dst, const char *src)
|
||||||
|
{
|
||||||
|
char ch;
|
||||||
|
char prev = '\0';
|
||||||
|
|
||||||
|
while ((ch = *src++) != '\0') {
|
||||||
|
if (prev == '/' && ch == prev)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
*dst++ = ch;
|
||||||
|
prev = ch;
|
||||||
|
}
|
||||||
|
*dst = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
|
int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
|
if (argc == 2 && !strcmp(argv[1], "-h"))
|
||||||
|
usage(builtin_check_ref_format_usage);
|
||||||
|
|
||||||
if (argc == 3 && !strcmp(argv[1], "--branch")) {
|
if (argc == 3 && !strcmp(argv[1], "--branch")) {
|
||||||
struct strbuf sb = STRBUF_INIT;
|
struct strbuf sb = STRBUF_INIT;
|
||||||
|
|
||||||
@ -17,7 +46,16 @@ int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
|
|||||||
printf("%s\n", sb.buf + 11);
|
printf("%s\n", sb.buf + 11);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
if (argc == 3 && !strcmp(argv[1], "--print")) {
|
||||||
|
char *refname = xmalloc(strlen(argv[2]) + 1);
|
||||||
|
|
||||||
|
if (check_ref_format(argv[2]))
|
||||||
|
exit(1);
|
||||||
|
collapse_slashes(refname, argv[2]);
|
||||||
|
printf("%s\n", refname);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
if (argc != 2)
|
if (argc != 2)
|
||||||
usage("git check-ref-format refname");
|
usage(builtin_check_ref_format_usage);
|
||||||
return !!check_ref_format(argv[1]);
|
return !!check_ref_format(argv[1]);
|
||||||
}
|
}
|
||||||
|
@ -302,8 +302,9 @@ static void show_local_changes(struct object *head)
|
|||||||
static void describe_detached_head(char *msg, struct commit *commit)
|
static void describe_detached_head(char *msg, struct commit *commit)
|
||||||
{
|
{
|
||||||
struct strbuf sb = STRBUF_INIT;
|
struct strbuf sb = STRBUF_INIT;
|
||||||
|
struct pretty_print_context ctx = {0};
|
||||||
parse_commit(commit);
|
parse_commit(commit);
|
||||||
pretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, 0, NULL, NULL, 0, 0);
|
pretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, &ctx);
|
||||||
fprintf(stderr, "%s %s... %s\n", msg,
|
fprintf(stderr, "%s %s... %s\n", msg,
|
||||||
find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV), sb.buf);
|
find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV), sb.buf);
|
||||||
strbuf_release(&sb);
|
strbuf_release(&sb);
|
||||||
@ -572,6 +573,40 @@ static int interactive_checkout(const char *revision, const char **pathspec,
|
|||||||
return run_add_interactive(revision, "--patch=checkout", pathspec);
|
return run_add_interactive(revision, "--patch=checkout", pathspec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct tracking_name_data {
|
||||||
|
const char *name;
|
||||||
|
char *remote;
|
||||||
|
int unique;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int check_tracking_name(const char *refname, const unsigned char *sha1,
|
||||||
|
int flags, void *cb_data)
|
||||||
|
{
|
||||||
|
struct tracking_name_data *cb = cb_data;
|
||||||
|
const char *slash;
|
||||||
|
|
||||||
|
if (prefixcmp(refname, "refs/remotes/"))
|
||||||
|
return 0;
|
||||||
|
slash = strchr(refname + 13, '/');
|
||||||
|
if (!slash || strcmp(slash + 1, cb->name))
|
||||||
|
return 0;
|
||||||
|
if (cb->remote) {
|
||||||
|
cb->unique = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
cb->remote = xstrdup(refname);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *unique_tracking_name(const char *name)
|
||||||
|
{
|
||||||
|
struct tracking_name_data cb_data = { name, NULL, 1 };
|
||||||
|
for_each_ref(check_tracking_name, &cb_data);
|
||||||
|
if (cb_data.unique)
|
||||||
|
return cb_data.remote;
|
||||||
|
free(cb_data.remote);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int cmd_checkout(int argc, const char **argv, const char *prefix)
|
int cmd_checkout(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
@ -582,6 +617,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
|
|||||||
struct tree *source_tree = NULL;
|
struct tree *source_tree = NULL;
|
||||||
char *conflict_style = NULL;
|
char *conflict_style = NULL;
|
||||||
int patch_mode = 0;
|
int patch_mode = 0;
|
||||||
|
int dwim_new_local_branch = 1;
|
||||||
struct option options[] = {
|
struct option options[] = {
|
||||||
OPT__QUIET(&opts.quiet),
|
OPT__QUIET(&opts.quiet),
|
||||||
OPT_STRING('b', NULL, &opts.new_branch, "new branch", "branch"),
|
OPT_STRING('b', NULL, &opts.new_branch, "new branch", "branch"),
|
||||||
@ -597,6 +633,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
|
|||||||
OPT_STRING(0, "conflict", &conflict_style, "style",
|
OPT_STRING(0, "conflict", &conflict_style, "style",
|
||||||
"conflict style (merge or diff3)"),
|
"conflict style (merge or diff3)"),
|
||||||
OPT_BOOLEAN('p', "patch", &patch_mode, "select hunks interactively"),
|
OPT_BOOLEAN('p', "patch", &patch_mode, "select hunks interactively"),
|
||||||
|
{ OPTION_BOOLEAN, 0, "guess", &dwim_new_local_branch, NULL,
|
||||||
|
"second guess 'git checkout no-such-branch'",
|
||||||
|
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
|
||||||
OPT_END(),
|
OPT_END(),
|
||||||
};
|
};
|
||||||
int has_dash_dash;
|
int has_dash_dash;
|
||||||
@ -630,8 +669,6 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
|
|||||||
opts.new_branch = argv0 + 1;
|
opts.new_branch = argv0 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.track == BRANCH_TRACK_UNSPECIFIED)
|
|
||||||
opts.track = git_branch_track;
|
|
||||||
if (conflict_style) {
|
if (conflict_style) {
|
||||||
opts.merge = 1; /* implied */
|
opts.merge = 1; /* implied */
|
||||||
git_xmerge_config("merge.conflictstyle", conflict_style, NULL);
|
git_xmerge_config("merge.conflictstyle", conflict_style, NULL);
|
||||||
@ -655,6 +692,11 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
|
|||||||
* With no paths, if <something> is a commit, that is to
|
* With no paths, if <something> is a commit, that is to
|
||||||
* switch to the branch or detach HEAD at it.
|
* switch to the branch or detach HEAD at it.
|
||||||
*
|
*
|
||||||
|
* With no paths, if <something> is _not_ a commit, no -t nor -b
|
||||||
|
* was given, and there is a tracking branch whose name is
|
||||||
|
* <something> in one and only one remote, then this is a short-hand
|
||||||
|
* to fork local <something> from that remote tracking branch.
|
||||||
|
*
|
||||||
* Otherwise <something> shall not be ambiguous.
|
* Otherwise <something> shall not be ambiguous.
|
||||||
* - If it's *only* a reference, treat it like case (1).
|
* - If it's *only* a reference, treat it like case (1).
|
||||||
* - If it's only a path, treat it like case (2).
|
* - If it's only a path, treat it like case (2).
|
||||||
@ -677,7 +719,21 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
|
|||||||
if (get_sha1(arg, rev)) {
|
if (get_sha1(arg, rev)) {
|
||||||
if (has_dash_dash) /* case (1) */
|
if (has_dash_dash) /* case (1) */
|
||||||
die("invalid reference: %s", arg);
|
die("invalid reference: %s", arg);
|
||||||
goto no_reference; /* case (3 -> 2) */
|
if (!patch_mode &&
|
||||||
|
dwim_new_local_branch &&
|
||||||
|
opts.track == BRANCH_TRACK_UNSPECIFIED &&
|
||||||
|
!opts.new_branch &&
|
||||||
|
!check_filename(NULL, arg) &&
|
||||||
|
argc == 1) {
|
||||||
|
const char *remote = unique_tracking_name(arg);
|
||||||
|
if (!remote || get_sha1(remote, rev))
|
||||||
|
goto no_reference;
|
||||||
|
opts.new_branch = arg;
|
||||||
|
arg = remote;
|
||||||
|
/* DWIMmed to create local branch */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
goto no_reference;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we can't end up being in (2) anymore, eat the argument */
|
/* we can't end up being in (2) anymore, eat the argument */
|
||||||
@ -715,6 +771,10 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
|
|||||||
}
|
}
|
||||||
|
|
||||||
no_reference:
|
no_reference:
|
||||||
|
|
||||||
|
if (opts.track == BRANCH_TRACK_UNSPECIFIED)
|
||||||
|
opts.track = git_branch_track;
|
||||||
|
|
||||||
if (argc) {
|
if (argc) {
|
||||||
const char **pathspec = get_pathspec(prefix, argv);
|
const char **pathspec = get_pathspec(prefix, argv);
|
||||||
|
|
||||||
|
@ -51,7 +51,9 @@ static struct option builtin_clone_options[] = {
|
|||||||
OPT_BOOLEAN('n', "no-checkout", &option_no_checkout,
|
OPT_BOOLEAN('n', "no-checkout", &option_no_checkout,
|
||||||
"don't create a checkout"),
|
"don't create a checkout"),
|
||||||
OPT_BOOLEAN(0, "bare", &option_bare, "create a bare repository"),
|
OPT_BOOLEAN(0, "bare", &option_bare, "create a bare repository"),
|
||||||
OPT_BOOLEAN(0, "naked", &option_bare, "create a bare repository"),
|
{ OPTION_BOOLEAN, 0, "naked", &option_bare, NULL,
|
||||||
|
"create a bare repository",
|
||||||
|
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
|
||||||
OPT_BOOLEAN(0, "mirror", &option_mirror,
|
OPT_BOOLEAN(0, "mirror", &option_mirror,
|
||||||
"create a mirror repository (implies bare)"),
|
"create a mirror repository (implies bare)"),
|
||||||
OPT_BOOLEAN('l', "local", &option_local,
|
OPT_BOOLEAN('l', "local", &option_local,
|
||||||
@ -61,7 +63,7 @@ static struct option builtin_clone_options[] = {
|
|||||||
OPT_BOOLEAN('s', "shared", &option_shared,
|
OPT_BOOLEAN('s', "shared", &option_shared,
|
||||||
"setup as shared repository"),
|
"setup as shared repository"),
|
||||||
OPT_BOOLEAN(0, "recursive", &option_recursive,
|
OPT_BOOLEAN(0, "recursive", &option_recursive,
|
||||||
"setup as shared repository"),
|
"initialize submodules in the clone"),
|
||||||
OPT_STRING(0, "template", &option_template, "path",
|
OPT_STRING(0, "template", &option_template, "path",
|
||||||
"path the template repository"),
|
"path the template repository"),
|
||||||
OPT_STRING(0, "reference", &option_reference, "repo",
|
OPT_STRING(0, "reference", &option_reference, "repo",
|
||||||
@ -377,8 +379,13 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||||||
argc = parse_options(argc, argv, prefix, builtin_clone_options,
|
argc = parse_options(argc, argv, prefix, builtin_clone_options,
|
||||||
builtin_clone_usage, 0);
|
builtin_clone_usage, 0);
|
||||||
|
|
||||||
|
if (argc > 2)
|
||||||
|
usage_msg_opt("Too many arguments.",
|
||||||
|
builtin_clone_usage, builtin_clone_options);
|
||||||
|
|
||||||
if (argc == 0)
|
if (argc == 0)
|
||||||
die("You must specify a repository to clone.");
|
usage_msg_opt("You must specify a repository to clone.",
|
||||||
|
builtin_clone_usage, builtin_clone_options);
|
||||||
|
|
||||||
if (option_mirror)
|
if (option_mirror)
|
||||||
option_bare = 1;
|
option_bare = 1;
|
||||||
@ -641,7 +648,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||||||
die("unable to write new index file");
|
die("unable to write new index file");
|
||||||
|
|
||||||
err |= run_hook(NULL, "post-checkout", sha1_to_hex(null_sha1),
|
err |= run_hook(NULL, "post-checkout", sha1_to_hex(null_sha1),
|
||||||
sha1_to_hex(remote_head->old_sha1), "1", NULL);
|
sha1_to_hex(our_head_points_at->old_sha1), "1",
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (!err && option_recursive)
|
if (!err && option_recursive)
|
||||||
err = run_command_v_opt(argv_submodule, RUN_GIT_CMD);
|
err = run_command_v_opt(argv_submodule, RUN_GIT_CMD);
|
||||||
|
@ -105,7 +105,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
|
|||||||
|
|
||||||
git_config(git_default_config, NULL);
|
git_config(git_default_config, NULL);
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2 || !strcmp(argv[1], "-h"))
|
||||||
usage(commit_tree_usage);
|
usage(commit_tree_usage);
|
||||||
if (get_sha1(argv[1], tree_sha1))
|
if (get_sha1(argv[1], tree_sha1))
|
||||||
die("Not a valid object name %s", argv[1]);
|
die("Not a valid object name %s", argv[1]);
|
||||||
|
@ -414,6 +414,47 @@ static void determine_author_info(void)
|
|||||||
author_date = date;
|
author_date = date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ends_rfc2822_footer(struct strbuf *sb)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
int hit = 0;
|
||||||
|
int i, j, k;
|
||||||
|
int len = sb->len;
|
||||||
|
int first = 1;
|
||||||
|
const char *buf = sb->buf;
|
||||||
|
|
||||||
|
for (i = len - 1; i > 0; i--) {
|
||||||
|
if (hit && buf[i] == '\n')
|
||||||
|
break;
|
||||||
|
hit = (buf[i] == '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i < len - 1 && buf[i] == '\n')
|
||||||
|
i++;
|
||||||
|
|
||||||
|
for (; i < len; i = k) {
|
||||||
|
for (k = i; k < len && buf[k] != '\n'; k++)
|
||||||
|
; /* do nothing */
|
||||||
|
k++;
|
||||||
|
|
||||||
|
if ((buf[k] == ' ' || buf[k] == '\t') && !first)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
first = 0;
|
||||||
|
|
||||||
|
for (j = 0; i + j < len; j++) {
|
||||||
|
ch = buf[i + j];
|
||||||
|
if (ch == ':')
|
||||||
|
break;
|
||||||
|
if (isalnum(ch) ||
|
||||||
|
(ch == '-'))
|
||||||
|
continue;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int prepare_to_commit(const char *index_file, const char *prefix,
|
static int prepare_to_commit(const char *index_file, const char *prefix,
|
||||||
struct wt_status *s)
|
struct wt_status *s)
|
||||||
{
|
{
|
||||||
@ -489,7 +530,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
|
|||||||
for (i = sb.len - 1; i > 0 && sb.buf[i - 1] != '\n'; i--)
|
for (i = sb.len - 1; i > 0 && sb.buf[i - 1] != '\n'; i--)
|
||||||
; /* do nothing */
|
; /* do nothing */
|
||||||
if (prefixcmp(sb.buf + i, sob.buf)) {
|
if (prefixcmp(sb.buf + i, sob.buf)) {
|
||||||
if (prefixcmp(sb.buf + i, sign_off_header))
|
if (!i || !ends_rfc2822_footer(&sb))
|
||||||
strbuf_addch(&sb, '\n');
|
strbuf_addch(&sb, '\n');
|
||||||
strbuf_addbuf(&sb, &sob);
|
strbuf_addbuf(&sb, &sob);
|
||||||
}
|
}
|
||||||
@ -684,8 +725,10 @@ static const char *find_author_by_nickname(const char *name)
|
|||||||
prepare_revision_walk(&revs);
|
prepare_revision_walk(&revs);
|
||||||
commit = get_revision(&revs);
|
commit = get_revision(&revs);
|
||||||
if (commit) {
|
if (commit) {
|
||||||
|
struct pretty_print_context ctx = {0};
|
||||||
|
ctx.date_mode = DATE_NORMAL;
|
||||||
strbuf_release(&buf);
|
strbuf_release(&buf);
|
||||||
format_commit_message(commit, "%an <%ae>", &buf, DATE_NORMAL);
|
format_commit_message(commit, "%an <%ae>", &buf, &ctx);
|
||||||
return strbuf_detach(&buf, NULL);
|
return strbuf_detach(&buf, NULL);
|
||||||
}
|
}
|
||||||
die("No existing author found with '%s'", name);
|
die("No existing author found with '%s'", name);
|
||||||
@ -942,8 +985,10 @@ static void print_summary(const char *prefix, const unsigned char *sha1)
|
|||||||
initial_commit ? " (root-commit)" : "");
|
initial_commit ? " (root-commit)" : "");
|
||||||
|
|
||||||
if (!log_tree_commit(&rev, commit)) {
|
if (!log_tree_commit(&rev, commit)) {
|
||||||
|
struct pretty_print_context ctx = {0};
|
||||||
struct strbuf buf = STRBUF_INIT;
|
struct strbuf buf = STRBUF_INIT;
|
||||||
format_commit_message(commit, format + 7, &buf, DATE_NORMAL);
|
ctx.date_mode = DATE_NORMAL;
|
||||||
|
format_commit_message(commit, format + 7, &buf, &ctx);
|
||||||
printf("%s\n", buf.buf);
|
printf("%s\n", buf.buf);
|
||||||
strbuf_release(&buf);
|
strbuf_release(&buf);
|
||||||
}
|
}
|
||||||
@ -954,7 +999,7 @@ static int git_commit_config(const char *k, const char *v, void *cb)
|
|||||||
struct wt_status *s = cb;
|
struct wt_status *s = cb;
|
||||||
|
|
||||||
if (!strcmp(k, "commit.template"))
|
if (!strcmp(k, "commit.template"))
|
||||||
return git_config_string(&template_file, k, v);
|
return git_config_pathname(&template_file, k, v);
|
||||||
|
|
||||||
return git_status_config(k, v, s);
|
return git_status_config(k, v, s);
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,14 @@
|
|||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
#include "exec_cmd.h"
|
#include "exec_cmd.h"
|
||||||
#include "parse-options.h"
|
#include "parse-options.h"
|
||||||
|
#include "diff.h"
|
||||||
|
|
||||||
#define SEEN (1u<<0)
|
#define SEEN (1u<<0)
|
||||||
#define MAX_TAGS (FLAG_BITS - 1)
|
#define MAX_TAGS (FLAG_BITS - 1)
|
||||||
|
|
||||||
static const char * const describe_usage[] = {
|
static const char * const describe_usage[] = {
|
||||||
"git describe [options] <committish>*",
|
"git describe [options] <committish>*",
|
||||||
|
"git describe [options] --dirty",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -23,6 +25,13 @@ static int max_candidates = 10;
|
|||||||
static int found_names;
|
static int found_names;
|
||||||
static const char *pattern;
|
static const char *pattern;
|
||||||
static int always;
|
static int always;
|
||||||
|
static const char *dirty;
|
||||||
|
|
||||||
|
/* diff-index command arguments to check if working tree is dirty. */
|
||||||
|
static const char *diff_index_args[] = {
|
||||||
|
"diff-index", "--quiet", "HEAD", "--", NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct commit_name {
|
struct commit_name {
|
||||||
struct tag *tag;
|
struct tag *tag;
|
||||||
@ -96,8 +105,6 @@ static int get_name(const char *path, const unsigned char *sha1, int flag, void
|
|||||||
if (!all) {
|
if (!all) {
|
||||||
if (!prio)
|
if (!prio)
|
||||||
return 0;
|
return 0;
|
||||||
if (!tags && prio < 2)
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
add_to_known_names(all ? path + 5 : path + 10, commit, prio, sha1);
|
add_to_known_names(all ? path + 5 : path + 10, commit, prio, sha1);
|
||||||
return 0;
|
return 0;
|
||||||
@ -180,11 +187,11 @@ static void describe(const char *arg, int last_one)
|
|||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
struct commit *cmit, *gave_up_on = NULL;
|
struct commit *cmit, *gave_up_on = NULL;
|
||||||
struct commit_list *list;
|
struct commit_list *list;
|
||||||
static int initialized = 0;
|
|
||||||
struct commit_name *n;
|
struct commit_name *n;
|
||||||
struct possible_tag all_matches[MAX_TAGS];
|
struct possible_tag all_matches[MAX_TAGS];
|
||||||
unsigned int match_cnt = 0, annotated_cnt = 0, cur_match;
|
unsigned int match_cnt = 0, annotated_cnt = 0, cur_match;
|
||||||
unsigned long seen_commits = 0;
|
unsigned long seen_commits = 0;
|
||||||
|
unsigned int unannotated_cnt = 0;
|
||||||
|
|
||||||
if (get_sha1(arg, sha1))
|
if (get_sha1(arg, sha1))
|
||||||
die("Not a valid object name %s", arg);
|
die("Not a valid object name %s", arg);
|
||||||
@ -192,22 +199,16 @@ static void describe(const char *arg, int last_one)
|
|||||||
if (!cmit)
|
if (!cmit)
|
||||||
die("%s is not a valid '%s' object", arg, commit_type);
|
die("%s is not a valid '%s' object", arg, commit_type);
|
||||||
|
|
||||||
if (!initialized) {
|
|
||||||
initialized = 1;
|
|
||||||
for_each_ref(get_name, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found_names)
|
|
||||||
die("cannot describe '%s'", sha1_to_hex(sha1));
|
|
||||||
|
|
||||||
n = cmit->util;
|
n = cmit->util;
|
||||||
if (n) {
|
if (n && (tags || all || n->prio == 2)) {
|
||||||
/*
|
/*
|
||||||
* Exact match to an existing ref.
|
* Exact match to an existing ref.
|
||||||
*/
|
*/
|
||||||
display_name(n);
|
display_name(n);
|
||||||
if (longformat)
|
if (longformat)
|
||||||
show_suffix(0, n->tag ? n->tag->tagged->sha1 : sha1);
|
show_suffix(0, n->tag ? n->tag->tagged->sha1 : sha1);
|
||||||
|
if (dirty)
|
||||||
|
printf("%s", dirty);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -226,7 +227,9 @@ static void describe(const char *arg, int last_one)
|
|||||||
seen_commits++;
|
seen_commits++;
|
||||||
n = c->util;
|
n = c->util;
|
||||||
if (n) {
|
if (n) {
|
||||||
if (match_cnt < max_candidates) {
|
if (!tags && !all && n->prio < 2) {
|
||||||
|
unannotated_cnt++;
|
||||||
|
} else if (match_cnt < max_candidates) {
|
||||||
struct possible_tag *t = &all_matches[match_cnt++];
|
struct possible_tag *t = &all_matches[match_cnt++];
|
||||||
t->name = n;
|
t->name = n;
|
||||||
t->depth = seen_commits - 1;
|
t->depth = seen_commits - 1;
|
||||||
@ -265,10 +268,20 @@ static void describe(const char *arg, int last_one)
|
|||||||
if (!match_cnt) {
|
if (!match_cnt) {
|
||||||
const unsigned char *sha1 = cmit->object.sha1;
|
const unsigned char *sha1 = cmit->object.sha1;
|
||||||
if (always) {
|
if (always) {
|
||||||
printf("%s\n", find_unique_abbrev(sha1, abbrev));
|
printf("%s", find_unique_abbrev(sha1, abbrev));
|
||||||
|
if (dirty)
|
||||||
|
printf("%s", dirty);
|
||||||
|
printf("\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
die("cannot describe '%s'", sha1_to_hex(sha1));
|
if (unannotated_cnt)
|
||||||
|
die("No annotated tags can describe '%s'.\n"
|
||||||
|
"However, there were unannotated tags: try --tags.",
|
||||||
|
sha1_to_hex(sha1));
|
||||||
|
else
|
||||||
|
die("No tags can describe '%s'.\n"
|
||||||
|
"Try --always, or create some tags.",
|
||||||
|
sha1_to_hex(sha1));
|
||||||
}
|
}
|
||||||
|
|
||||||
qsort(all_matches, match_cnt, sizeof(all_matches[0]), compare_pt);
|
qsort(all_matches, match_cnt, sizeof(all_matches[0]), compare_pt);
|
||||||
@ -300,6 +313,8 @@ static void describe(const char *arg, int last_one)
|
|||||||
display_name(all_matches[0].name);
|
display_name(all_matches[0].name);
|
||||||
if (abbrev)
|
if (abbrev)
|
||||||
show_suffix(all_matches[0].depth, cmit->object.sha1);
|
show_suffix(all_matches[0].depth, cmit->object.sha1);
|
||||||
|
if (dirty)
|
||||||
|
printf("%s", dirty);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
if (!last_one)
|
if (!last_one)
|
||||||
@ -324,6 +339,9 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
|
|||||||
"only consider tags matching <pattern>"),
|
"only consider tags matching <pattern>"),
|
||||||
OPT_BOOLEAN(0, "always", &always,
|
OPT_BOOLEAN(0, "always", &always,
|
||||||
"show abbreviated commit object as fallback"),
|
"show abbreviated commit object as fallback"),
|
||||||
|
{OPTION_STRING, 0, "dirty", &dirty, "mark",
|
||||||
|
"append <mark> on dirty working tree (default: \"-dirty\")",
|
||||||
|
PARSE_OPT_OPTARG, NULL, (intptr_t) "-dirty"},
|
||||||
OPT_END(),
|
OPT_END(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -359,8 +377,16 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
|
|||||||
return cmd_name_rev(i + argc, args, prefix);
|
return cmd_name_rev(i + argc, args, prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for_each_ref(get_name, NULL);
|
||||||
|
if (!found_names && !always)
|
||||||
|
die("No names found, cannot describe anything.");
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
|
if (dirty && !cmd_diff_index(ARRAY_SIZE(diff_index_args) - 1, diff_index_args, prefix))
|
||||||
|
dirty = NULL;
|
||||||
describe("HEAD", 1);
|
describe("HEAD", 1);
|
||||||
|
} else if (dirty) {
|
||||||
|
die("--dirty is incompatible with committishes");
|
||||||
} else {
|
} else {
|
||||||
while (argc-- > 0) {
|
while (argc-- > 0) {
|
||||||
describe(*argv++, argc == 0);
|
describe(*argv++, argc == 0);
|
||||||
|
@ -104,6 +104,7 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
|
|||||||
git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
|
git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
|
||||||
opt->abbrev = 0;
|
opt->abbrev = 0;
|
||||||
opt->diff = 1;
|
opt->diff = 1;
|
||||||
|
opt->disable_stdin = 1;
|
||||||
argc = setup_revisions(argc, argv, opt, NULL);
|
argc = setup_revisions(argc, argv, opt, NULL);
|
||||||
|
|
||||||
while (--argc > 0) {
|
while (--argc > 0) {
|
||||||
|
@ -157,6 +157,66 @@ static const unsigned char *get_rev(void)
|
|||||||
return commit->object.sha1;
|
return commit->object.sha1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ack_type {
|
||||||
|
NAK = 0,
|
||||||
|
ACK,
|
||||||
|
ACK_continue,
|
||||||
|
ACK_common,
|
||||||
|
ACK_ready
|
||||||
|
};
|
||||||
|
|
||||||
|
static void consume_shallow_list(int fd)
|
||||||
|
{
|
||||||
|
if (args.stateless_rpc && args.depth > 0) {
|
||||||
|
/* If we sent a depth we will get back "duplicate"
|
||||||
|
* shallow and unshallow commands every time there
|
||||||
|
* is a block of have lines exchanged.
|
||||||
|
*/
|
||||||
|
char line[1000];
|
||||||
|
while (packet_read_line(fd, line, sizeof(line))) {
|
||||||
|
if (!prefixcmp(line, "shallow "))
|
||||||
|
continue;
|
||||||
|
if (!prefixcmp(line, "unshallow "))
|
||||||
|
continue;
|
||||||
|
die("git fetch-pack: expected shallow list");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum ack_type get_ack(int fd, unsigned char *result_sha1)
|
||||||
|
{
|
||||||
|
static char line[1000];
|
||||||
|
int len = packet_read_line(fd, line, sizeof(line));
|
||||||
|
|
||||||
|
if (!len)
|
||||||
|
die("git fetch-pack: expected ACK/NAK, got EOF");
|
||||||
|
if (line[len-1] == '\n')
|
||||||
|
line[--len] = 0;
|
||||||
|
if (!strcmp(line, "NAK"))
|
||||||
|
return NAK;
|
||||||
|
if (!prefixcmp(line, "ACK ")) {
|
||||||
|
if (!get_sha1_hex(line+4, result_sha1)) {
|
||||||
|
if (strstr(line+45, "continue"))
|
||||||
|
return ACK_continue;
|
||||||
|
if (strstr(line+45, "common"))
|
||||||
|
return ACK_common;
|
||||||
|
if (strstr(line+45, "ready"))
|
||||||
|
return ACK_ready;
|
||||||
|
return ACK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
die("git fetch_pack: expected ACK/NAK, got '%s'", line);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void send_request(int fd, struct strbuf *buf)
|
||||||
|
{
|
||||||
|
if (args.stateless_rpc) {
|
||||||
|
send_sideband(fd, -1, buf->buf, buf->len, LARGE_PACKET_MAX);
|
||||||
|
packet_flush(fd);
|
||||||
|
} else
|
||||||
|
safe_write(fd, buf->buf, buf->len);
|
||||||
|
}
|
||||||
|
|
||||||
static int find_common(int fd[2], unsigned char *result_sha1,
|
static int find_common(int fd[2], unsigned char *result_sha1,
|
||||||
struct ref *refs)
|
struct ref *refs)
|
||||||
{
|
{
|
||||||
@ -165,7 +225,11 @@ static int find_common(int fd[2], unsigned char *result_sha1,
|
|||||||
const unsigned char *sha1;
|
const unsigned char *sha1;
|
||||||
unsigned in_vain = 0;
|
unsigned in_vain = 0;
|
||||||
int got_continue = 0;
|
int got_continue = 0;
|
||||||
|
struct strbuf req_buf = STRBUF_INIT;
|
||||||
|
size_t state_len = 0;
|
||||||
|
|
||||||
|
if (args.stateless_rpc && multi_ack == 1)
|
||||||
|
die("--stateless-rpc requires multi_ack_detailed");
|
||||||
if (marked)
|
if (marked)
|
||||||
for_each_ref(clear_marks, NULL);
|
for_each_ref(clear_marks, NULL);
|
||||||
marked = 1;
|
marked = 1;
|
||||||
@ -175,6 +239,7 @@ static int find_common(int fd[2], unsigned char *result_sha1,
|
|||||||
fetching = 0;
|
fetching = 0;
|
||||||
for ( ; refs ; refs = refs->next) {
|
for ( ; refs ; refs = refs->next) {
|
||||||
unsigned char *remote = refs->old_sha1;
|
unsigned char *remote = refs->old_sha1;
|
||||||
|
const char *remote_hex;
|
||||||
struct object *o;
|
struct object *o;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -192,32 +257,42 @@ static int find_common(int fd[2], unsigned char *result_sha1,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fetching)
|
remote_hex = sha1_to_hex(remote);
|
||||||
packet_write(fd[1], "want %s%s%s%s%s%s%s%s\n",
|
if (!fetching) {
|
||||||
sha1_to_hex(remote),
|
struct strbuf c = STRBUF_INIT;
|
||||||
(multi_ack ? " multi_ack" : ""),
|
if (multi_ack == 2) strbuf_addstr(&c, " multi_ack_detailed");
|
||||||
(use_sideband == 2 ? " side-band-64k" : ""),
|
if (multi_ack == 1) strbuf_addstr(&c, " multi_ack");
|
||||||
(use_sideband == 1 ? " side-band" : ""),
|
if (use_sideband == 2) strbuf_addstr(&c, " side-band-64k");
|
||||||
(args.use_thin_pack ? " thin-pack" : ""),
|
if (use_sideband == 1) strbuf_addstr(&c, " side-band");
|
||||||
(args.no_progress ? " no-progress" : ""),
|
if (args.use_thin_pack) strbuf_addstr(&c, " thin-pack");
|
||||||
(args.include_tag ? " include-tag" : ""),
|
if (args.no_progress) strbuf_addstr(&c, " no-progress");
|
||||||
(prefer_ofs_delta ? " ofs-delta" : ""));
|
if (args.include_tag) strbuf_addstr(&c, " include-tag");
|
||||||
else
|
if (prefer_ofs_delta) strbuf_addstr(&c, " ofs-delta");
|
||||||
packet_write(fd[1], "want %s\n", sha1_to_hex(remote));
|
packet_buf_write(&req_buf, "want %s%s\n", remote_hex, c.buf);
|
||||||
|
strbuf_release(&c);
|
||||||
|
} else
|
||||||
|
packet_buf_write(&req_buf, "want %s\n", remote_hex);
|
||||||
fetching++;
|
fetching++;
|
||||||
}
|
}
|
||||||
if (is_repository_shallow())
|
|
||||||
write_shallow_commits(fd[1], 1);
|
if (!fetching) {
|
||||||
if (args.depth > 0)
|
strbuf_release(&req_buf);
|
||||||
packet_write(fd[1], "deepen %d", args.depth);
|
|
||||||
packet_flush(fd[1]);
|
packet_flush(fd[1]);
|
||||||
if (!fetching)
|
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_repository_shallow())
|
||||||
|
write_shallow_commits(&req_buf, 1);
|
||||||
|
if (args.depth > 0)
|
||||||
|
packet_buf_write(&req_buf, "deepen %d", args.depth);
|
||||||
|
packet_buf_flush(&req_buf);
|
||||||
|
state_len = req_buf.len;
|
||||||
|
|
||||||
if (args.depth > 0) {
|
if (args.depth > 0) {
|
||||||
char line[1024];
|
char line[1024];
|
||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
|
|
||||||
|
send_request(fd[1], &req_buf);
|
||||||
while (packet_read_line(fd[0], line, sizeof(line))) {
|
while (packet_read_line(fd[0], line, sizeof(line))) {
|
||||||
if (!prefixcmp(line, "shallow ")) {
|
if (!prefixcmp(line, "shallow ")) {
|
||||||
if (get_sha1_hex(line + 8, sha1))
|
if (get_sha1_hex(line + 8, sha1))
|
||||||
@ -239,45 +314,73 @@ static int find_common(int fd[2], unsigned char *result_sha1,
|
|||||||
}
|
}
|
||||||
die("expected shallow/unshallow, got %s", line);
|
die("expected shallow/unshallow, got %s", line);
|
||||||
}
|
}
|
||||||
|
} else if (!args.stateless_rpc)
|
||||||
|
send_request(fd[1], &req_buf);
|
||||||
|
|
||||||
|
if (!args.stateless_rpc) {
|
||||||
|
/* If we aren't using the stateless-rpc interface
|
||||||
|
* we don't need to retain the headers.
|
||||||
|
*/
|
||||||
|
strbuf_setlen(&req_buf, 0);
|
||||||
|
state_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
flushes = 0;
|
flushes = 0;
|
||||||
retval = -1;
|
retval = -1;
|
||||||
while ((sha1 = get_rev())) {
|
while ((sha1 = get_rev())) {
|
||||||
packet_write(fd[1], "have %s\n", sha1_to_hex(sha1));
|
packet_buf_write(&req_buf, "have %s\n", sha1_to_hex(sha1));
|
||||||
if (args.verbose)
|
if (args.verbose)
|
||||||
fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
|
fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
|
||||||
in_vain++;
|
in_vain++;
|
||||||
if (!(31 & ++count)) {
|
if (!(31 & ++count)) {
|
||||||
int ack;
|
int ack;
|
||||||
|
|
||||||
packet_flush(fd[1]);
|
packet_buf_flush(&req_buf);
|
||||||
|
send_request(fd[1], &req_buf);
|
||||||
|
strbuf_setlen(&req_buf, state_len);
|
||||||
flushes++;
|
flushes++;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We keep one window "ahead" of the other side, and
|
* We keep one window "ahead" of the other side, and
|
||||||
* will wait for an ACK only on the next one
|
* will wait for an ACK only on the next one
|
||||||
*/
|
*/
|
||||||
if (count == 32)
|
if (!args.stateless_rpc && count == 32)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
consume_shallow_list(fd[0]);
|
||||||
do {
|
do {
|
||||||
ack = get_ack(fd[0], result_sha1);
|
ack = get_ack(fd[0], result_sha1);
|
||||||
if (args.verbose && ack)
|
if (args.verbose && ack)
|
||||||
fprintf(stderr, "got ack %d %s\n", ack,
|
fprintf(stderr, "got ack %d %s\n", ack,
|
||||||
sha1_to_hex(result_sha1));
|
sha1_to_hex(result_sha1));
|
||||||
if (ack == 1) {
|
switch (ack) {
|
||||||
|
case ACK:
|
||||||
flushes = 0;
|
flushes = 0;
|
||||||
multi_ack = 0;
|
multi_ack = 0;
|
||||||
retval = 0;
|
retval = 0;
|
||||||
goto done;
|
goto done;
|
||||||
} else if (ack == 2) {
|
case ACK_common:
|
||||||
|
case ACK_ready:
|
||||||
|
case ACK_continue: {
|
||||||
struct commit *commit =
|
struct commit *commit =
|
||||||
lookup_commit(result_sha1);
|
lookup_commit(result_sha1);
|
||||||
|
if (args.stateless_rpc
|
||||||
|
&& ack == ACK_common
|
||||||
|
&& !(commit->object.flags & COMMON)) {
|
||||||
|
/* We need to replay the have for this object
|
||||||
|
* on the next RPC request so the peer knows
|
||||||
|
* it is in common with us.
|
||||||
|
*/
|
||||||
|
const char *hex = sha1_to_hex(result_sha1);
|
||||||
|
packet_buf_write(&req_buf, "have %s\n", hex);
|
||||||
|
state_len = req_buf.len;
|
||||||
|
}
|
||||||
mark_common(commit, 0, 1);
|
mark_common(commit, 0, 1);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
in_vain = 0;
|
in_vain = 0;
|
||||||
got_continue = 1;
|
got_continue = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (ack);
|
} while (ack);
|
||||||
flushes--;
|
flushes--;
|
||||||
@ -289,20 +392,24 @@ static int find_common(int fd[2], unsigned char *result_sha1,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
packet_write(fd[1], "done\n");
|
packet_buf_write(&req_buf, "done\n");
|
||||||
|
send_request(fd[1], &req_buf);
|
||||||
if (args.verbose)
|
if (args.verbose)
|
||||||
fprintf(stderr, "done\n");
|
fprintf(stderr, "done\n");
|
||||||
if (retval != 0) {
|
if (retval != 0) {
|
||||||
multi_ack = 0;
|
multi_ack = 0;
|
||||||
flushes++;
|
flushes++;
|
||||||
}
|
}
|
||||||
|
strbuf_release(&req_buf);
|
||||||
|
|
||||||
|
consume_shallow_list(fd[0]);
|
||||||
while (flushes || multi_ack) {
|
while (flushes || multi_ack) {
|
||||||
int ack = get_ack(fd[0], result_sha1);
|
int ack = get_ack(fd[0], result_sha1);
|
||||||
if (ack) {
|
if (ack) {
|
||||||
if (args.verbose)
|
if (args.verbose)
|
||||||
fprintf(stderr, "got ack (%d) %s\n", ack,
|
fprintf(stderr, "got ack (%d) %s\n", ack,
|
||||||
sha1_to_hex(result_sha1));
|
sha1_to_hex(result_sha1));
|
||||||
if (ack == 1)
|
if (ack == ACK)
|
||||||
return 0;
|
return 0;
|
||||||
multi_ack = 1;
|
multi_ack = 1;
|
||||||
continue;
|
continue;
|
||||||
@ -584,7 +691,12 @@ static struct ref *do_fetch_pack(int fd[2],
|
|||||||
|
|
||||||
if (is_repository_shallow() && !server_supports("shallow"))
|
if (is_repository_shallow() && !server_supports("shallow"))
|
||||||
die("Server does not support shallow clients");
|
die("Server does not support shallow clients");
|
||||||
if (server_supports("multi_ack")) {
|
if (server_supports("multi_ack_detailed")) {
|
||||||
|
if (args.verbose)
|
||||||
|
fprintf(stderr, "Server supports multi_ack_detailed\n");
|
||||||
|
multi_ack = 2;
|
||||||
|
}
|
||||||
|
else if (server_supports("multi_ack")) {
|
||||||
if (args.verbose)
|
if (args.verbose)
|
||||||
fprintf(stderr, "Server supports multi_ack\n");
|
fprintf(stderr, "Server supports multi_ack\n");
|
||||||
multi_ack = 1;
|
multi_ack = 1;
|
||||||
@ -615,6 +727,8 @@ static struct ref *do_fetch_pack(int fd[2],
|
|||||||
*/
|
*/
|
||||||
warning("no common commits");
|
warning("no common commits");
|
||||||
|
|
||||||
|
if (args.stateless_rpc)
|
||||||
|
packet_flush(fd[1]);
|
||||||
if (get_pack(fd, pack_lockfile))
|
if (get_pack(fd, pack_lockfile))
|
||||||
die("git fetch-pack: fetch failed.");
|
die("git fetch-pack: fetch failed.");
|
||||||
|
|
||||||
@ -685,6 +799,8 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
|
|||||||
struct ref *ref = NULL;
|
struct ref *ref = NULL;
|
||||||
char *dest = NULL, **heads;
|
char *dest = NULL, **heads;
|
||||||
int fd[2];
|
int fd[2];
|
||||||
|
char *pack_lockfile = NULL;
|
||||||
|
char **pack_lockfile_ptr = NULL;
|
||||||
struct child_process *conn;
|
struct child_process *conn;
|
||||||
|
|
||||||
nr_heads = 0;
|
nr_heads = 0;
|
||||||
@ -734,6 +850,15 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
|
|||||||
args.no_progress = 1;
|
args.no_progress = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!strcmp("--stateless-rpc", arg)) {
|
||||||
|
args.stateless_rpc = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strcmp("--lock-pack", arg)) {
|
||||||
|
args.lock_pack = 1;
|
||||||
|
pack_lockfile_ptr = &pack_lockfile;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
usage(fetch_pack_usage);
|
usage(fetch_pack_usage);
|
||||||
}
|
}
|
||||||
dest = (char *)arg;
|
dest = (char *)arg;
|
||||||
@ -744,19 +869,27 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
|
|||||||
if (!dest)
|
if (!dest)
|
||||||
usage(fetch_pack_usage);
|
usage(fetch_pack_usage);
|
||||||
|
|
||||||
|
if (args.stateless_rpc) {
|
||||||
|
conn = NULL;
|
||||||
|
fd[0] = 0;
|
||||||
|
fd[1] = 1;
|
||||||
|
} else {
|
||||||
conn = git_connect(fd, (char *)dest, args.uploadpack,
|
conn = git_connect(fd, (char *)dest, args.uploadpack,
|
||||||
args.verbose ? CONNECT_VERBOSE : 0);
|
args.verbose ? CONNECT_VERBOSE : 0);
|
||||||
if (conn) {
|
}
|
||||||
|
|
||||||
get_remote_heads(fd[0], &ref, 0, NULL, 0, NULL);
|
get_remote_heads(fd[0], &ref, 0, NULL, 0, NULL);
|
||||||
|
|
||||||
ref = fetch_pack(&args, fd, conn, ref, dest, nr_heads, heads, NULL);
|
ref = fetch_pack(&args, fd, conn, ref, dest,
|
||||||
|
nr_heads, heads, pack_lockfile_ptr);
|
||||||
|
if (pack_lockfile) {
|
||||||
|
printf("lock %s\n", pack_lockfile);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
close(fd[0]);
|
close(fd[0]);
|
||||||
close(fd[1]);
|
close(fd[1]);
|
||||||
if (finish_connect(conn))
|
if (finish_connect(conn))
|
||||||
ref = NULL;
|
ref = NULL;
|
||||||
} else {
|
|
||||||
ref = NULL;
|
|
||||||
}
|
|
||||||
ret = !ref;
|
ret = !ref;
|
||||||
|
|
||||||
if (!ret && nr_heads) {
|
if (!ret && nr_heads) {
|
||||||
@ -809,6 +942,7 @@ struct ref *fetch_pack(struct fetch_pack_args *my_args,
|
|||||||
|
|
||||||
if (args.depth > 0) {
|
if (args.depth > 0) {
|
||||||
struct cache_time mtime;
|
struct cache_time mtime;
|
||||||
|
struct strbuf sb = STRBUF_INIT;
|
||||||
char *shallow = git_path("shallow");
|
char *shallow = git_path("shallow");
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
@ -826,12 +960,14 @@ struct ref *fetch_pack(struct fetch_pack_args *my_args,
|
|||||||
|
|
||||||
fd = hold_lock_file_for_update(&lock, shallow,
|
fd = hold_lock_file_for_update(&lock, shallow,
|
||||||
LOCK_DIE_ON_ERROR);
|
LOCK_DIE_ON_ERROR);
|
||||||
if (!write_shallow_commits(fd, 0)) {
|
if (!write_shallow_commits(&sb, 0)
|
||||||
|
|| write_in_full(fd, sb.buf, sb.len) != sb.len) {
|
||||||
unlink_or_warn(shallow);
|
unlink_or_warn(shallow);
|
||||||
rollback_lock_file(&lock);
|
rollback_lock_file(&lock);
|
||||||
} else {
|
} else {
|
||||||
commit_lock_file(&lock);
|
commit_lock_file(&lock);
|
||||||
}
|
}
|
||||||
|
strbuf_release(&sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
reprepare_packed_git();
|
reprepare_packed_git();
|
||||||
|
326
builtin-fetch.c
326
builtin-fetch.c
@ -14,6 +14,9 @@
|
|||||||
|
|
||||||
static const char * const builtin_fetch_usage[] = {
|
static const char * const builtin_fetch_usage[] = {
|
||||||
"git fetch [options] [<repository> <refspec>...]",
|
"git fetch [options] [<repository> <refspec>...]",
|
||||||
|
"git fetch [options] <group>",
|
||||||
|
"git fetch --multiple [options] [<repository> | <group>]...",
|
||||||
|
"git fetch --all [options]",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -23,7 +26,7 @@ enum {
|
|||||||
TAGS_SET = 2
|
TAGS_SET = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
static int append, force, keep, update_head_ok, verbosity;
|
static int all, append, dry_run, force, keep, multiple, prune, update_head_ok, verbosity;
|
||||||
static int tags = TAGS_DEFAULT;
|
static int tags = TAGS_DEFAULT;
|
||||||
static const char *depth;
|
static const char *depth;
|
||||||
static const char *upload_pack;
|
static const char *upload_pack;
|
||||||
@ -32,16 +35,24 @@ static struct transport *transport;
|
|||||||
|
|
||||||
static struct option builtin_fetch_options[] = {
|
static struct option builtin_fetch_options[] = {
|
||||||
OPT__VERBOSITY(&verbosity),
|
OPT__VERBOSITY(&verbosity),
|
||||||
|
OPT_BOOLEAN(0, "all", &all,
|
||||||
|
"fetch from all remotes"),
|
||||||
OPT_BOOLEAN('a', "append", &append,
|
OPT_BOOLEAN('a', "append", &append,
|
||||||
"append to .git/FETCH_HEAD instead of overwriting"),
|
"append to .git/FETCH_HEAD instead of overwriting"),
|
||||||
OPT_STRING(0, "upload-pack", &upload_pack, "PATH",
|
OPT_STRING(0, "upload-pack", &upload_pack, "PATH",
|
||||||
"path to upload pack on remote end"),
|
"path to upload pack on remote end"),
|
||||||
OPT_BOOLEAN('f', "force", &force,
|
OPT_BOOLEAN('f', "force", &force,
|
||||||
"force overwrite of local branch"),
|
"force overwrite of local branch"),
|
||||||
|
OPT_BOOLEAN('m', "multiple", &multiple,
|
||||||
|
"fetch from multiple remotes"),
|
||||||
OPT_SET_INT('t', "tags", &tags,
|
OPT_SET_INT('t', "tags", &tags,
|
||||||
"fetch all tags and associated objects", TAGS_SET),
|
"fetch all tags and associated objects", TAGS_SET),
|
||||||
OPT_SET_INT('n', NULL, &tags,
|
OPT_SET_INT('n', NULL, &tags,
|
||||||
"do not fetch all tags (--no-tags)", TAGS_UNSET),
|
"do not fetch all tags (--no-tags)", TAGS_UNSET),
|
||||||
|
OPT_BOOLEAN('p', "prune", &prune,
|
||||||
|
"prune tracking branches no longer on remote"),
|
||||||
|
OPT_BOOLEAN(0, "dry-run", &dry_run,
|
||||||
|
"dry run"),
|
||||||
OPT_BOOLEAN('k', "keep", &keep, "keep downloaded pack"),
|
OPT_BOOLEAN('k', "keep", &keep, "keep downloaded pack"),
|
||||||
OPT_BOOLEAN('u', "update-head-ok", &update_head_ok,
|
OPT_BOOLEAN('u', "update-head-ok", &update_head_ok,
|
||||||
"allow updating of HEAD ref"),
|
"allow updating of HEAD ref"),
|
||||||
@ -178,6 +189,8 @@ static int s_update_ref(const char *action,
|
|||||||
char *rla = getenv("GIT_REFLOG_ACTION");
|
char *rla = getenv("GIT_REFLOG_ACTION");
|
||||||
static struct ref_lock *lock;
|
static struct ref_lock *lock;
|
||||||
|
|
||||||
|
if (dry_run)
|
||||||
|
return 0;
|
||||||
if (!rla)
|
if (!rla)
|
||||||
rla = default_rla.buf;
|
rla = default_rla.buf;
|
||||||
snprintf(msg, sizeof(msg), "%s: %s", rla, action);
|
snprintf(msg, sizeof(msg), "%s: %s", rla, action);
|
||||||
@ -269,7 +282,7 @@ static int update_local_ref(struct ref *ref,
|
|||||||
strcpy(quickref, find_unique_abbrev(current->object.sha1, DEFAULT_ABBREV));
|
strcpy(quickref, find_unique_abbrev(current->object.sha1, DEFAULT_ABBREV));
|
||||||
strcat(quickref, "..");
|
strcat(quickref, "..");
|
||||||
strcat(quickref, find_unique_abbrev(ref->new_sha1, DEFAULT_ABBREV));
|
strcat(quickref, find_unique_abbrev(ref->new_sha1, DEFAULT_ABBREV));
|
||||||
r = s_update_ref("fast forward", ref, 1);
|
r = s_update_ref("fast-forward", ref, 1);
|
||||||
sprintf(display, "%c %-*s %-*s -> %s%s", r ? '!' : ' ',
|
sprintf(display, "%c %-*s %-*s -> %s%s", r ? '!' : ' ',
|
||||||
SUMMARY_WIDTH, quickref, REFCOL_WIDTH, remote,
|
SUMMARY_WIDTH, quickref, REFCOL_WIDTH, remote,
|
||||||
pretty_ref, r ? " (unable to update local ref)" : "");
|
pretty_ref, r ? " (unable to update local ref)" : "");
|
||||||
@ -287,7 +300,7 @@ static int update_local_ref(struct ref *ref,
|
|||||||
r ? "unable to update local ref" : "forced update");
|
r ? "unable to update local ref" : "forced update");
|
||||||
return r;
|
return r;
|
||||||
} else {
|
} else {
|
||||||
sprintf(display, "! %-*s %-*s -> %s (non fast forward)",
|
sprintf(display, "! %-*s %-*s -> %s (non-fast-forward)",
|
||||||
SUMMARY_WIDTH, "[rejected]", REFCOL_WIDTH, remote,
|
SUMMARY_WIDTH, "[rejected]", REFCOL_WIDTH, remote,
|
||||||
pretty_ref);
|
pretty_ref);
|
||||||
return 1;
|
return 1;
|
||||||
@ -303,7 +316,7 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
|
|||||||
char note[1024];
|
char note[1024];
|
||||||
const char *what, *kind;
|
const char *what, *kind;
|
||||||
struct ref *rm;
|
struct ref *rm;
|
||||||
char *url, *filename = git_path("FETCH_HEAD");
|
char *url, *filename = dry_run ? "/dev/null" : git_path("FETCH_HEAD");
|
||||||
|
|
||||||
fp = fopen(filename, "a");
|
fp = fopen(filename, "a");
|
||||||
if (!fp)
|
if (!fp)
|
||||||
@ -485,11 +498,34 @@ static int fetch_refs(struct transport *transport, struct ref *ref_map)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int prune_refs(struct transport *transport, struct ref *ref_map)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
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";
|
||||||
|
|
||||||
|
for (ref = stale_refs; ref; ref = ref->next) {
|
||||||
|
if (!dry_run)
|
||||||
|
result |= delete_ref(ref->name, NULL, 0);
|
||||||
|
if (verbosity >= 0) {
|
||||||
|
fprintf(stderr, " x %-*s %-*s -> %s\n",
|
||||||
|
SUMMARY_WIDTH, "[deleted]",
|
||||||
|
REFCOL_WIDTH, "(none)", prettify_refname(ref->name));
|
||||||
|
warn_dangling_symref(stderr, dangling_msg, ref->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free_refs(stale_refs);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static int add_existing(const char *refname, const unsigned char *sha1,
|
static int add_existing(const char *refname, const unsigned char *sha1,
|
||||||
int flag, void *cbdata)
|
int flag, void *cbdata)
|
||||||
{
|
{
|
||||||
struct string_list *list = (struct string_list *)cbdata;
|
struct string_list *list = (struct string_list *)cbdata;
|
||||||
string_list_insert(refname, list);
|
struct string_list_item *item = string_list_insert(refname, list);
|
||||||
|
item->util = (void *)sha1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -504,57 +540,98 @@ static int will_fetch(struct ref **head, const unsigned char *sha1)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct tag_data {
|
||||||
|
struct ref **head;
|
||||||
|
struct ref ***tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int add_to_tail(struct string_list_item *item, void *cb_data)
|
||||||
|
{
|
||||||
|
struct tag_data *data = (struct tag_data *)cb_data;
|
||||||
|
struct ref *rm = NULL;
|
||||||
|
|
||||||
|
/* We have already decided to ignore this item */
|
||||||
|
if (!item->util)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
rm = alloc_ref(item->string);
|
||||||
|
rm->peer_ref = alloc_ref(item->string);
|
||||||
|
hashcpy(rm->old_sha1, item->util);
|
||||||
|
|
||||||
|
**data->tail = rm;
|
||||||
|
*data->tail = &rm->next;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void find_non_local_tags(struct transport *transport,
|
static void find_non_local_tags(struct transport *transport,
|
||||||
struct ref **head,
|
struct ref **head,
|
||||||
struct ref ***tail)
|
struct ref ***tail)
|
||||||
{
|
{
|
||||||
struct string_list existing_refs = { NULL, 0, 0, 0 };
|
struct string_list existing_refs = { NULL, 0, 0, 0 };
|
||||||
struct string_list new_refs = { NULL, 0, 0, 1 };
|
struct string_list remote_refs = { NULL, 0, 0, 0 };
|
||||||
char *ref_name;
|
struct tag_data data = {head, tail};
|
||||||
int ref_name_len;
|
|
||||||
const unsigned char *ref_sha1;
|
|
||||||
const struct ref *tag_ref;
|
|
||||||
struct ref *rm = NULL;
|
|
||||||
const struct ref *ref;
|
const struct ref *ref;
|
||||||
|
struct string_list_item *item = NULL;
|
||||||
|
|
||||||
for_each_ref(add_existing, &existing_refs);
|
for_each_ref(add_existing, &existing_refs);
|
||||||
for (ref = transport_get_remote_refs(transport); ref; ref = ref->next) {
|
for (ref = transport_get_remote_refs(transport); ref; ref = ref->next) {
|
||||||
if (prefixcmp(ref->name, "refs/tags"))
|
if (prefixcmp(ref->name, "refs/tags"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ref_name = xstrdup(ref->name);
|
/*
|
||||||
ref_name_len = strlen(ref_name);
|
* The peeled ref always follows the matching base
|
||||||
ref_sha1 = ref->old_sha1;
|
* ref, so if we see a peeled ref that we don't want
|
||||||
|
* to fetch then we can mark the ref entry in the list
|
||||||
if (!strcmp(ref_name + ref_name_len - 3, "^{}")) {
|
* as one to ignore by setting util to NULL.
|
||||||
ref_name[ref_name_len - 3] = 0;
|
*/
|
||||||
tag_ref = transport_get_remote_refs(transport);
|
if (!strcmp(ref->name + strlen(ref->name) - 3, "^{}")) {
|
||||||
while (tag_ref) {
|
if (item && !has_sha1_file(ref->old_sha1) &&
|
||||||
if (!strcmp(tag_ref->name, ref_name)) {
|
!will_fetch(head, ref->old_sha1) &&
|
||||||
ref_sha1 = tag_ref->old_sha1;
|
!has_sha1_file(item->util) &&
|
||||||
break;
|
!will_fetch(head, item->util))
|
||||||
}
|
item->util = NULL;
|
||||||
tag_ref = tag_ref->next;
|
item = NULL;
|
||||||
}
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string_list_has_string(&existing_refs, ref_name) &&
|
/*
|
||||||
!string_list_has_string(&new_refs, ref_name) &&
|
* If item is non-NULL here, then we previously saw a
|
||||||
(has_sha1_file(ref->old_sha1) ||
|
* ref not followed by a peeled reference, so we need
|
||||||
will_fetch(head, ref->old_sha1))) {
|
* to check if it is a lightweight tag that we want to
|
||||||
string_list_insert(ref_name, &new_refs);
|
* fetch.
|
||||||
|
*/
|
||||||
|
if (item && !has_sha1_file(item->util) &&
|
||||||
|
!will_fetch(head, item->util))
|
||||||
|
item->util = NULL;
|
||||||
|
|
||||||
rm = alloc_ref(ref_name);
|
item = NULL;
|
||||||
rm->peer_ref = alloc_ref(ref_name);
|
|
||||||
hashcpy(rm->old_sha1, ref_sha1);
|
|
||||||
|
|
||||||
**tail = rm;
|
/* skip duplicates and refs that we already have */
|
||||||
*tail = &rm->next;
|
if (string_list_has_string(&remote_refs, ref->name) ||
|
||||||
}
|
string_list_has_string(&existing_refs, ref->name))
|
||||||
free(ref_name);
|
continue;
|
||||||
|
|
||||||
|
item = string_list_insert(ref->name, &remote_refs);
|
||||||
|
item->util = (void *)ref->old_sha1;
|
||||||
}
|
}
|
||||||
string_list_clear(&existing_refs, 0);
|
string_list_clear(&existing_refs, 0);
|
||||||
string_list_clear(&new_refs, 0);
|
|
||||||
|
/*
|
||||||
|
* We may have a final lightweight tag that needs to be
|
||||||
|
* checked to see if it needs fetching.
|
||||||
|
*/
|
||||||
|
if (item && !has_sha1_file(item->util) &&
|
||||||
|
!will_fetch(head, item->util))
|
||||||
|
item->util = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For all the tags in the remote_refs string list, call
|
||||||
|
* add_to_tail to add them to the list of refs to be fetched
|
||||||
|
*/
|
||||||
|
for_each_string_list(add_to_tail, &remote_refs, &data);
|
||||||
|
|
||||||
|
string_list_clear(&remote_refs, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_not_current_branch(struct ref *ref_map)
|
static void check_not_current_branch(struct ref *ref_map)
|
||||||
@ -574,9 +651,14 @@ static void check_not_current_branch(struct ref *ref_map)
|
|||||||
static int do_fetch(struct transport *transport,
|
static int do_fetch(struct transport *transport,
|
||||||
struct refspec *refs, int ref_count)
|
struct refspec *refs, int ref_count)
|
||||||
{
|
{
|
||||||
|
struct string_list existing_refs = { NULL, 0, 0, 0 };
|
||||||
|
struct string_list_item *peer_item = NULL;
|
||||||
struct ref *ref_map;
|
struct ref *ref_map;
|
||||||
struct ref *rm;
|
struct ref *rm;
|
||||||
int autotags = (transport->remote->fetch_tags == 1);
|
int autotags = (transport->remote->fetch_tags == 1);
|
||||||
|
|
||||||
|
for_each_ref(add_existing, &existing_refs);
|
||||||
|
|
||||||
if (transport->remote->fetch_tags == 2 && tags != TAGS_UNSET)
|
if (transport->remote->fetch_tags == 2 && tags != TAGS_UNSET)
|
||||||
tags = TAGS_SET;
|
tags = TAGS_SET;
|
||||||
if (transport->remote->fetch_tags == -1)
|
if (transport->remote->fetch_tags == -1)
|
||||||
@ -586,7 +668,7 @@ static int do_fetch(struct transport *transport,
|
|||||||
die("Don't know how to fetch from %s", transport->url);
|
die("Don't know how to fetch from %s", transport->url);
|
||||||
|
|
||||||
/* if not appending, truncate FETCH_HEAD */
|
/* if not appending, truncate FETCH_HEAD */
|
||||||
if (!append) {
|
if (!append && !dry_run) {
|
||||||
char *filename = git_path("FETCH_HEAD");
|
char *filename = git_path("FETCH_HEAD");
|
||||||
FILE *fp = fopen(filename, "w");
|
FILE *fp = fopen(filename, "w");
|
||||||
if (!fp)
|
if (!fp)
|
||||||
@ -599,8 +681,13 @@ static int do_fetch(struct transport *transport,
|
|||||||
check_not_current_branch(ref_map);
|
check_not_current_branch(ref_map);
|
||||||
|
|
||||||
for (rm = ref_map; rm; rm = rm->next) {
|
for (rm = ref_map; rm; rm = rm->next) {
|
||||||
if (rm->peer_ref)
|
if (rm->peer_ref) {
|
||||||
read_ref(rm->peer_ref->name, rm->peer_ref->old_sha1);
|
peer_item = string_list_lookup(rm->peer_ref->name,
|
||||||
|
&existing_refs);
|
||||||
|
if (peer_item)
|
||||||
|
hashcpy(rm->peer_ref->old_sha1,
|
||||||
|
peer_item->util);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tags == TAGS_DEFAULT && autotags)
|
if (tags == TAGS_DEFAULT && autotags)
|
||||||
@ -609,6 +696,8 @@ static int do_fetch(struct transport *transport,
|
|||||||
free_refs(ref_map);
|
free_refs(ref_map);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (prune)
|
||||||
|
prune_refs(transport, ref_map);
|
||||||
free_refs(ref_map);
|
free_refs(ref_map);
|
||||||
|
|
||||||
/* if neither --no-tags nor --tags was specified, do automated tag
|
/* if neither --no-tags nor --tags was specified, do automated tag
|
||||||
@ -639,33 +728,100 @@ static void set_option(const char *name, const char *value)
|
|||||||
name, transport->url);
|
name, transport->url);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_fetch(int argc, const char **argv, const char *prefix)
|
static int get_one_remote_for_fetch(struct remote *remote, void *priv)
|
||||||
{
|
{
|
||||||
|
struct string_list *list = priv;
|
||||||
|
if (!remote->skip_default_update)
|
||||||
|
string_list_append(remote->name, list);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct remote_group_data {
|
||||||
|
const char *name;
|
||||||
|
struct string_list *list;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int get_remote_group(const char *key, const char *value, void *priv)
|
||||||
|
{
|
||||||
|
struct remote_group_data *g = priv;
|
||||||
|
|
||||||
|
if (!prefixcmp(key, "remotes.") &&
|
||||||
|
!strcmp(key + 8, g->name)) {
|
||||||
|
/* split list by white space */
|
||||||
|
int space = strcspn(value, " \t\n");
|
||||||
|
while (*value) {
|
||||||
|
if (space > 1) {
|
||||||
|
string_list_append(xstrndup(value, space),
|
||||||
|
g->list);
|
||||||
|
}
|
||||||
|
value += space + (value[space] != '\0');
|
||||||
|
space = strcspn(value, " \t\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int add_remote_or_group(const char *name, struct string_list *list)
|
||||||
|
{
|
||||||
|
int prev_nr = list->nr;
|
||||||
|
struct remote_group_data g = { name, list };
|
||||||
|
|
||||||
|
git_config(get_remote_group, &g);
|
||||||
|
if (list->nr == prev_nr) {
|
||||||
struct remote *remote;
|
struct remote *remote;
|
||||||
|
if (!remote_is_configured(name))
|
||||||
|
return 0;
|
||||||
|
remote = remote_get(name);
|
||||||
|
string_list_append(remote->name, list);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fetch_multiple(struct string_list *list)
|
||||||
|
{
|
||||||
|
int i, result = 0;
|
||||||
|
const char *argv[] = { "fetch", NULL, NULL, NULL, NULL, NULL, NULL };
|
||||||
|
int argc = 1;
|
||||||
|
|
||||||
|
if (dry_run)
|
||||||
|
argv[argc++] = "--dry-run";
|
||||||
|
if (prune)
|
||||||
|
argv[argc++] = "--prune";
|
||||||
|
if (verbosity >= 2)
|
||||||
|
argv[argc++] = "-v";
|
||||||
|
if (verbosity >= 1)
|
||||||
|
argv[argc++] = "-v";
|
||||||
|
else if (verbosity < 0)
|
||||||
|
argv[argc++] = "-q";
|
||||||
|
|
||||||
|
for (i = 0; i < list->nr; i++) {
|
||||||
|
const char *name = list->items[i].string;
|
||||||
|
argv[argc] = name;
|
||||||
|
if (verbosity >= 0)
|
||||||
|
printf("Fetching %s\n", name);
|
||||||
|
if (run_command_v_opt(argv, RUN_GIT_CMD)) {
|
||||||
|
error("Could not fetch %s", name);
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fetch_one(struct remote *remote, int argc, const char **argv)
|
||||||
|
{
|
||||||
int i;
|
int i;
|
||||||
static const char **refs = NULL;
|
static const char **refs = NULL;
|
||||||
int ref_nr = 0;
|
int ref_nr = 0;
|
||||||
int exit_code;
|
int exit_code;
|
||||||
|
|
||||||
/* Record the command line for the reflog */
|
|
||||||
strbuf_addstr(&default_rla, "fetch");
|
|
||||||
for (i = 1; i < argc; i++)
|
|
||||||
strbuf_addf(&default_rla, " %s", argv[i]);
|
|
||||||
|
|
||||||
argc = parse_options(argc, argv, prefix,
|
|
||||||
builtin_fetch_options, builtin_fetch_usage, 0);
|
|
||||||
|
|
||||||
if (argc == 0)
|
|
||||||
remote = remote_get(NULL);
|
|
||||||
else
|
|
||||||
remote = remote_get(argv[0]);
|
|
||||||
|
|
||||||
if (!remote)
|
if (!remote)
|
||||||
die("Where do you want to fetch from today?");
|
die("Where do you want to fetch from today?");
|
||||||
|
|
||||||
transport = transport_get(remote, remote->url[0]);
|
transport = transport_get(remote, remote->url[0]);
|
||||||
if (verbosity >= 2)
|
if (verbosity >= 2)
|
||||||
transport->verbose = 1;
|
transport->verbose = verbosity <= 3 ? verbosity : 3;
|
||||||
if (verbosity < 0)
|
if (verbosity < 0)
|
||||||
transport->verbose = -1;
|
transport->verbose = -1;
|
||||||
if (upload_pack)
|
if (upload_pack)
|
||||||
@ -675,10 +831,10 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
|
|||||||
if (depth)
|
if (depth)
|
||||||
set_option(TRANS_OPT_DEPTH, depth);
|
set_option(TRANS_OPT_DEPTH, depth);
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 0) {
|
||||||
int j = 0;
|
int j = 0;
|
||||||
refs = xcalloc(argc + 1, sizeof(const char *));
|
refs = xcalloc(argc + 1, sizeof(const char *));
|
||||||
for (i = 1; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
if (!strcmp(argv[i], "tag")) {
|
if (!strcmp(argv[i], "tag")) {
|
||||||
char *ref;
|
char *ref;
|
||||||
i++;
|
i++;
|
||||||
@ -705,3 +861,57 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
|
|||||||
transport = NULL;
|
transport = NULL;
|
||||||
return exit_code;
|
return exit_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cmd_fetch(int argc, const char **argv, const char *prefix)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct string_list list = { NULL, 0, 0, 0 };
|
||||||
|
struct remote *remote;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
/* Record the command line for the reflog */
|
||||||
|
strbuf_addstr(&default_rla, "fetch");
|
||||||
|
for (i = 1; i < argc; i++)
|
||||||
|
strbuf_addf(&default_rla, " %s", argv[i]);
|
||||||
|
|
||||||
|
argc = parse_options(argc, argv, prefix,
|
||||||
|
builtin_fetch_options, builtin_fetch_usage, 0);
|
||||||
|
|
||||||
|
if (all) {
|
||||||
|
if (argc == 1)
|
||||||
|
die("fetch --all does not take a repository argument");
|
||||||
|
else if (argc > 1)
|
||||||
|
die("fetch --all does not make sense with refspecs");
|
||||||
|
(void) for_each_remote(get_one_remote_for_fetch, &list);
|
||||||
|
result = fetch_multiple(&list);
|
||||||
|
} else if (argc == 0) {
|
||||||
|
/* No arguments -- use default remote */
|
||||||
|
remote = remote_get(NULL);
|
||||||
|
result = fetch_one(remote, argc, argv);
|
||||||
|
} else if (multiple) {
|
||||||
|
/* All arguments are assumed to be remotes or groups */
|
||||||
|
for (i = 0; i < argc; i++)
|
||||||
|
if (!add_remote_or_group(argv[i], &list))
|
||||||
|
die("No such remote or remote group: %s", argv[i]);
|
||||||
|
result = fetch_multiple(&list);
|
||||||
|
} else {
|
||||||
|
/* Single remote or group */
|
||||||
|
(void) add_remote_or_group(argv[0], &list);
|
||||||
|
if (list.nr > 1) {
|
||||||
|
/* More than one remote */
|
||||||
|
if (argc > 1)
|
||||||
|
die("Fetching a group and specifying refspecs does not make sense");
|
||||||
|
result = fetch_multiple(&list);
|
||||||
|
} else {
|
||||||
|
/* Zero or one remotes */
|
||||||
|
remote = remote_get(argv[0]);
|
||||||
|
result = fetch_one(remote, argc-1, argv+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All names were strdup()ed or strndup()ed */
|
||||||
|
list.strdup_strings = 1;
|
||||||
|
string_list_clear(&list, 0);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
@ -19,7 +19,7 @@ static int show_root;
|
|||||||
static int show_tags;
|
static int show_tags;
|
||||||
static int show_unreachable;
|
static int show_unreachable;
|
||||||
static int include_reflogs = 1;
|
static int include_reflogs = 1;
|
||||||
static int check_full;
|
static int check_full = 1;
|
||||||
static int check_strict;
|
static int check_strict;
|
||||||
static int keep_cache_objects;
|
static int keep_cache_objects;
|
||||||
static unsigned char head_sha1[20];
|
static unsigned char head_sha1[20];
|
||||||
@ -47,6 +47,7 @@ static void objreport(struct object *obj, const char *severity,
|
|||||||
fputs("\n", stderr);
|
fputs("\n", stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__attribute__((format (printf, 2, 3)))
|
||||||
static int objerror(struct object *obj, const char *err, ...)
|
static int objerror(struct object *obj, const char *err, ...)
|
||||||
{
|
{
|
||||||
va_list params;
|
va_list params;
|
||||||
@ -57,6 +58,7 @@ static int objerror(struct object *obj, const char *err, ...)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__attribute__((format (printf, 3, 4)))
|
||||||
static int fsck_error_func(struct object *obj, int type, const char *err, ...)
|
static int fsck_error_func(struct object *obj, int type, const char *err, ...)
|
||||||
{
|
{
|
||||||
va_list params;
|
va_list params;
|
||||||
|
@ -216,10 +216,13 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
|
|||||||
*/
|
*/
|
||||||
if (!need_to_gc())
|
if (!need_to_gc())
|
||||||
return 0;
|
return 0;
|
||||||
fprintf(stderr, "Auto packing your repository for optimum "
|
fprintf(stderr,
|
||||||
"performance. You may also\n"
|
"Auto packing the repository for optimum performance.%s\n",
|
||||||
|
quiet
|
||||||
|
? ""
|
||||||
|
: (" You may also\n"
|
||||||
"run \"git gc\" manually. See "
|
"run \"git gc\" manually. See "
|
||||||
"\"git help gc\" for more information.\n");
|
"\"git help gc\" for more information."));
|
||||||
} else
|
} else
|
||||||
append_option(argv_repack,
|
append_option(argv_repack,
|
||||||
prune_expire && !strcmp(prune_expire, "now")
|
prune_expire && !strcmp(prune_expire, "now")
|
||||||
|
@ -367,7 +367,7 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
|
|||||||
push_arg("-h");
|
push_arg("-h");
|
||||||
if (opt->regflags & REG_EXTENDED)
|
if (opt->regflags & REG_EXTENDED)
|
||||||
push_arg("-E");
|
push_arg("-E");
|
||||||
if (opt->regflags & REG_ICASE)
|
if (opt->ignore_case)
|
||||||
push_arg("-i");
|
push_arg("-i");
|
||||||
if (opt->binary == GREP_BINARY_NOMATCH)
|
if (opt->binary == GREP_BINARY_NOMATCH)
|
||||||
push_arg("-I");
|
push_arg("-I");
|
||||||
@ -433,7 +433,11 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
|
|||||||
|
|
||||||
if (opt->color_external && strlen(opt->color_external) > 0)
|
if (opt->color_external && strlen(opt->color_external) > 0)
|
||||||
push_arg(opt->color_external);
|
push_arg(opt->color_external);
|
||||||
|
} else {
|
||||||
|
unsetenv("GREP_COLOR");
|
||||||
|
unsetenv("GREP_COLORS");
|
||||||
}
|
}
|
||||||
|
unsetenv("GREP_OPTIONS");
|
||||||
|
|
||||||
hit = 0;
|
hit = 0;
|
||||||
argc = nr;
|
argc = nr;
|
||||||
@ -631,7 +635,7 @@ static int file_callback(const struct option *opt, const char *arg, int unset)
|
|||||||
struct grep_opt *grep_opt = opt->value;
|
struct grep_opt *grep_opt = opt->value;
|
||||||
FILE *patterns;
|
FILE *patterns;
|
||||||
int lno = 0;
|
int lno = 0;
|
||||||
struct strbuf sb;
|
struct strbuf sb = STRBUF_INIT;
|
||||||
|
|
||||||
patterns = fopen(arg, "r");
|
patterns = fopen(arg, "r");
|
||||||
if (!patterns)
|
if (!patterns)
|
||||||
@ -706,8 +710,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
|||||||
OPT_GROUP(""),
|
OPT_GROUP(""),
|
||||||
OPT_BOOLEAN('v', "invert-match", &opt.invert,
|
OPT_BOOLEAN('v', "invert-match", &opt.invert,
|
||||||
"show non-matching lines"),
|
"show non-matching lines"),
|
||||||
OPT_BIT('i', "ignore-case", &opt.regflags,
|
OPT_BOOLEAN('i', "ignore-case", &opt.ignore_case,
|
||||||
"case insensitive matching", REG_ICASE),
|
"case insensitive matching"),
|
||||||
OPT_BOOLEAN('w', "word-regexp", &opt.word_regexp,
|
OPT_BOOLEAN('w', "word-regexp", &opt.word_regexp,
|
||||||
"match patterns only at word boundaries"),
|
"match patterns only at word boundaries"),
|
||||||
OPT_SET_INT('a', "text", &opt.binary,
|
OPT_SET_INT('a', "text", &opt.binary,
|
||||||
@ -788,6 +792,13 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
|||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 'git grep -h', unlike 'git grep -h <pattern>', is a request
|
||||||
|
* to show usage information and exit.
|
||||||
|
*/
|
||||||
|
if (argc == 2 && !strcmp(argv[1], "-h"))
|
||||||
|
usage_with_options(grep_usage, options);
|
||||||
|
|
||||||
memset(&opt, 0, sizeof(opt));
|
memset(&opt, 0, sizeof(opt));
|
||||||
opt.prefix = prefix;
|
opt.prefix = prefix;
|
||||||
opt.prefix_length = (prefix && *prefix) ? strlen(prefix) : 0;
|
opt.prefix_length = (prefix && *prefix) ? strlen(prefix) : 0;
|
||||||
@ -830,6 +841,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
|||||||
external_grep_allowed = 0;
|
external_grep_allowed = 0;
|
||||||
if (!opt.pattern_list)
|
if (!opt.pattern_list)
|
||||||
die("no pattern given.");
|
die("no pattern given.");
|
||||||
|
if (!opt.fixed && opt.ignore_case)
|
||||||
|
opt.regflags |= REG_ICASE;
|
||||||
if ((opt.regflags != REG_NEWLINE) && opt.fixed)
|
if ((opt.regflags != REG_NEWLINE) && opt.fixed)
|
||||||
die("cannot mix --fixed-strings and regexp");
|
die("cannot mix --fixed-strings and regexp");
|
||||||
compile_grep_patterns(&opt);
|
compile_grep_patterns(&opt);
|
||||||
|
@ -372,6 +372,7 @@ static void show_info_page(const char *git_cmd)
|
|||||||
const char *page = cmd_to_page(git_cmd);
|
const char *page = cmd_to_page(git_cmd);
|
||||||
setenv("INFOPATH", system_path(GIT_INFO_PATH), 1);
|
setenv("INFOPATH", system_path(GIT_INFO_PATH), 1);
|
||||||
execlp("info", "info", "gitman", page, NULL);
|
execlp("info", "info", "gitman", page, NULL);
|
||||||
|
die("no info viewer handled the request");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_html_page_path(struct strbuf *page_path, const char *page)
|
static void get_html_page_path(struct strbuf *page_path, const char *page)
|
||||||
@ -416,9 +417,6 @@ int cmd_help(int argc, const char **argv, const char *prefix)
|
|||||||
const char *alias;
|
const char *alias;
|
||||||
load_command_list("git-", &main_cmds, &other_cmds);
|
load_command_list("git-", &main_cmds, &other_cmds);
|
||||||
|
|
||||||
setup_git_directory_gently(&nongit);
|
|
||||||
git_config(git_help_config, NULL);
|
|
||||||
|
|
||||||
argc = parse_options(argc, argv, prefix, builtin_help_options,
|
argc = parse_options(argc, argv, prefix, builtin_help_options,
|
||||||
builtin_help_usage, 0);
|
builtin_help_usage, 0);
|
||||||
|
|
||||||
@ -429,6 +427,9 @@ int cmd_help(int argc, const char **argv, const char *prefix)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setup_git_directory_gently(&nongit);
|
||||||
|
git_config(git_help_config, NULL);
|
||||||
|
|
||||||
if (!argv[0]) {
|
if (!argv[0]) {
|
||||||
printf("usage: %s\n\n", git_usage_string);
|
printf("usage: %s\n\n", git_usage_string);
|
||||||
list_common_cmds_help();
|
list_common_cmds_help();
|
||||||
|
@ -50,6 +50,12 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
|
|||||||
if (default_date_mode)
|
if (default_date_mode)
|
||||||
rev->date_mode = parse_date_format(default_date_mode);
|
rev->date_mode = parse_date_format(default_date_mode);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for -h before setup_revisions(), or "git log -h" will
|
||||||
|
* fail when run without a git directory.
|
||||||
|
*/
|
||||||
|
if (argc == 2 && !strcmp(argv[1], "-h"))
|
||||||
|
usage(builtin_log_usage);
|
||||||
argc = setup_revisions(argc, argv, rev, "HEAD");
|
argc = setup_revisions(argc, argv, rev, "HEAD");
|
||||||
|
|
||||||
if (rev->diffopt.pickaxe || rev->diffopt.filter)
|
if (rev->diffopt.pickaxe || rev->diffopt.filter)
|
||||||
@ -891,6 +897,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
|||||||
struct patch_ids ids;
|
struct patch_ids ids;
|
||||||
char *add_signoff = NULL;
|
char *add_signoff = NULL;
|
||||||
struct strbuf buf = STRBUF_INIT;
|
struct strbuf buf = STRBUF_INIT;
|
||||||
|
int use_patch_format = 0;
|
||||||
const struct option builtin_format_patch_options[] = {
|
const struct option builtin_format_patch_options[] = {
|
||||||
{ OPTION_CALLBACK, 'n', "numbered", &numbered, NULL,
|
{ OPTION_CALLBACK, 'n', "numbered", &numbered, NULL,
|
||||||
"use [PATCH n/m] even with a single patch",
|
"use [PATCH n/m] even with a single patch",
|
||||||
@ -922,6 +929,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
|||||||
"don't output binary diffs"),
|
"don't output binary diffs"),
|
||||||
OPT_BOOLEAN(0, "ignore-if-in-upstream", &ignore_if_in_upstream,
|
OPT_BOOLEAN(0, "ignore-if-in-upstream", &ignore_if_in_upstream,
|
||||||
"don't include a patch matching a commit upstream"),
|
"don't include a patch matching a commit upstream"),
|
||||||
|
{ OPTION_BOOLEAN, 'p', "no-stat", &use_patch_format, NULL,
|
||||||
|
"show patch format instead of default (patch + stat)",
|
||||||
|
PARSE_OPT_NONEG | PARSE_OPT_NOARG },
|
||||||
OPT_GROUP("Messaging"),
|
OPT_GROUP("Messaging"),
|
||||||
{ OPTION_CALLBACK, 0, "add-header", NULL, "header",
|
{ OPTION_CALLBACK, 0, "add-header", NULL, "header",
|
||||||
"add email header", PARSE_OPT_NONEG,
|
"add email header", PARSE_OPT_NONEG,
|
||||||
@ -1027,9 +1037,20 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
|||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
die ("unrecognized argument: %s", argv[1]);
|
die ("unrecognized argument: %s", argv[1]);
|
||||||
|
|
||||||
if (!rev.diffopt.output_format
|
if (rev.diffopt.output_format & DIFF_FORMAT_NAME)
|
||||||
|| rev.diffopt.output_format == DIFF_FORMAT_PATCH)
|
die("--name-only does not make sense");
|
||||||
rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY | DIFF_FORMAT_PATCH;
|
if (rev.diffopt.output_format & DIFF_FORMAT_NAME_STATUS)
|
||||||
|
die("--name-status does not make sense");
|
||||||
|
if (rev.diffopt.output_format & DIFF_FORMAT_CHECKDIFF)
|
||||||
|
die("--check does not make sense");
|
||||||
|
|
||||||
|
if (!use_patch_format &&
|
||||||
|
(!rev.diffopt.output_format ||
|
||||||
|
rev.diffopt.output_format == DIFF_FORMAT_PATCH))
|
||||||
|
rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY;
|
||||||
|
|
||||||
|
/* Always generate a patch */
|
||||||
|
rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
|
||||||
|
|
||||||
if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff)
|
if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff)
|
||||||
DIFF_OPT_SET(&rev.diffopt, BINARY);
|
DIFF_OPT_SET(&rev.diffopt, BINARY);
|
||||||
@ -1237,6 +1258,9 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
|
|||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (argc > 1 && !strcmp(argv[1], "-h"))
|
||||||
|
usage(cherry_usage);
|
||||||
|
|
||||||
switch (argc) {
|
switch (argc) {
|
||||||
case 4:
|
case 4:
|
||||||
limit = argv[3];
|
limit = argv[3];
|
||||||
@ -1304,8 +1328,9 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
|
|||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
struct strbuf buf = STRBUF_INIT;
|
struct strbuf buf = STRBUF_INIT;
|
||||||
|
struct pretty_print_context ctx = {0};
|
||||||
pretty_print_commit(CMIT_FMT_ONELINE, commit,
|
pretty_print_commit(CMIT_FMT_ONELINE, commit,
|
||||||
&buf, 0, NULL, NULL, 0, 0);
|
&buf, &ctx);
|
||||||
printf("%c %s %s\n", sign,
|
printf("%c %s %s\n", sign,
|
||||||
sha1_to_hex(commit->object.sha1), buf.buf);
|
sha1_to_hex(commit->object.sha1), buf.buf);
|
||||||
strbuf_release(&buf);
|
strbuf_release(&buf);
|
||||||
|
@ -171,8 +171,8 @@ static void show_files(struct dir_struct *dir, const char *prefix)
|
|||||||
for (i = 0; i < active_nr; i++) {
|
for (i = 0; i < active_nr; i++) {
|
||||||
struct cache_entry *ce = active_cache[i];
|
struct cache_entry *ce = active_cache[i];
|
||||||
int dtype = ce_to_dtype(ce);
|
int dtype = ce_to_dtype(ce);
|
||||||
if (excluded(dir, ce->name, &dtype) !=
|
if (dir->flags & DIR_SHOW_IGNORED &&
|
||||||
!!(dir->flags & DIR_SHOW_IGNORED))
|
!excluded(dir, ce->name, &dtype))
|
||||||
continue;
|
continue;
|
||||||
if (show_unmerged && !ce_stage(ce))
|
if (show_unmerged && !ce_stage(ce))
|
||||||
continue;
|
continue;
|
||||||
@ -187,8 +187,8 @@ static void show_files(struct dir_struct *dir, const char *prefix)
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
int err;
|
int err;
|
||||||
int dtype = ce_to_dtype(ce);
|
int dtype = ce_to_dtype(ce);
|
||||||
if (excluded(dir, ce->name, &dtype) !=
|
if (dir->flags & DIR_SHOW_IGNORED &&
|
||||||
!!(dir->flags & DIR_SHOW_IGNORED))
|
!excluded(dir, ce->name, &dtype))
|
||||||
continue;
|
continue;
|
||||||
if (ce->ce_flags & CE_UPDATE)
|
if (ce->ce_flags & CE_UPDATE)
|
||||||
continue;
|
continue;
|
||||||
|
@ -86,10 +86,10 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
|
|||||||
pattern[j - i] = p;
|
pattern[j - i] = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
remote = nongit ? NULL : remote_get(dest);
|
remote = remote_get(dest);
|
||||||
if (remote && !remote->url_nr)
|
if (!remote->url_nr)
|
||||||
die("remote %s has no configured URL", dest);
|
die("remote %s has no configured URL", dest);
|
||||||
transport = transport_get(remote, remote ? remote->url[0] : dest);
|
transport = transport_get(remote, remote->url[0]);
|
||||||
if (uploadpack != NULL)
|
if (uploadpack != NULL)
|
||||||
transport_set_option(transport, TRANS_OPT_UPLOADPACK, uploadpack);
|
transport_set_option(transport, TRANS_OPT_UPLOADPACK, uploadpack);
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "quote.h"
|
#include "quote.h"
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
|
#include "parse-options.h"
|
||||||
|
|
||||||
static int line_termination = '\n';
|
static int line_termination = '\n';
|
||||||
#define LS_RECURSIVE 1
|
#define LS_RECURSIVE 1
|
||||||
@ -22,8 +23,10 @@ static const char **pathspec;
|
|||||||
static int chomp_prefix;
|
static int chomp_prefix;
|
||||||
static const char *ls_tree_prefix;
|
static const char *ls_tree_prefix;
|
||||||
|
|
||||||
static const char ls_tree_usage[] =
|
static const char * const ls_tree_usage[] = {
|
||||||
"git ls-tree [-d] [-r] [-t] [-l] [-z] [--name-only] [--name-status] [--full-name] [--full-tree] [--abbrev[=<n>]] <tree-ish> [path...]";
|
"git ls-tree [<options>] <tree-ish> [path...]",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
static int show_recursive(const char *base, int baselen, const char *pathname)
|
static int show_recursive(const char *base, int baselen, const char *pathname)
|
||||||
{
|
{
|
||||||
@ -117,76 +120,53 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
|
|||||||
{
|
{
|
||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
struct tree *tree;
|
struct tree *tree;
|
||||||
|
int full_tree = 0;
|
||||||
|
const struct option ls_tree_options[] = {
|
||||||
|
OPT_BIT('d', NULL, &ls_options, "only show trees",
|
||||||
|
LS_TREE_ONLY),
|
||||||
|
OPT_BIT('r', NULL, &ls_options, "recurse into subtrees",
|
||||||
|
LS_RECURSIVE),
|
||||||
|
OPT_BIT('t', NULL, &ls_options, "show trees when recursing",
|
||||||
|
LS_SHOW_TREES),
|
||||||
|
OPT_SET_INT('z', NULL, &line_termination,
|
||||||
|
"terminate entries with NUL byte", 0),
|
||||||
|
OPT_BIT('l', "long", &ls_options, "include object size",
|
||||||
|
LS_SHOW_SIZE),
|
||||||
|
OPT_BIT(0, "name-only", &ls_options, "list only filenames",
|
||||||
|
LS_NAME_ONLY),
|
||||||
|
OPT_BIT(0, "name-status", &ls_options, "list only filenames",
|
||||||
|
LS_NAME_ONLY),
|
||||||
|
OPT_SET_INT(0, "full-name", &chomp_prefix,
|
||||||
|
"use full path names", 0),
|
||||||
|
OPT_BOOLEAN(0, "full-tree", &full_tree,
|
||||||
|
"list entire tree; not just current directory "
|
||||||
|
"(implies --full-name)"),
|
||||||
|
OPT__ABBREV(&abbrev),
|
||||||
|
OPT_END()
|
||||||
|
};
|
||||||
|
|
||||||
git_config(git_default_config, NULL);
|
git_config(git_default_config, NULL);
|
||||||
ls_tree_prefix = prefix;
|
ls_tree_prefix = prefix;
|
||||||
if (prefix && *prefix)
|
if (prefix && *prefix)
|
||||||
chomp_prefix = strlen(prefix);
|
chomp_prefix = strlen(prefix);
|
||||||
while (1 < argc && argv[1][0] == '-') {
|
|
||||||
switch (argv[1][1]) {
|
argc = parse_options(argc, argv, prefix, ls_tree_options,
|
||||||
case 'z':
|
ls_tree_usage, 0);
|
||||||
line_termination = 0;
|
if (full_tree) {
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
ls_options |= LS_RECURSIVE;
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
ls_options |= LS_TREE_ONLY;
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
ls_options |= LS_SHOW_TREES;
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
ls_options |= LS_SHOW_SIZE;
|
|
||||||
break;
|
|
||||||
case '-':
|
|
||||||
if (!strcmp(argv[1]+2, "name-only") ||
|
|
||||||
!strcmp(argv[1]+2, "name-status")) {
|
|
||||||
ls_options |= LS_NAME_ONLY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!strcmp(argv[1]+2, "long")) {
|
|
||||||
ls_options |= LS_SHOW_SIZE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!strcmp(argv[1]+2, "full-name")) {
|
|
||||||
chomp_prefix = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!strcmp(argv[1]+2, "full-tree")) {
|
|
||||||
ls_tree_prefix = prefix = NULL;
|
ls_tree_prefix = prefix = NULL;
|
||||||
chomp_prefix = 0;
|
chomp_prefix = 0;
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!prefixcmp(argv[1]+2, "abbrev=")) {
|
|
||||||
abbrev = strtoul(argv[1]+9, NULL, 10);
|
|
||||||
if (abbrev && abbrev < MINIMUM_ABBREV)
|
|
||||||
abbrev = MINIMUM_ABBREV;
|
|
||||||
else if (abbrev > 40)
|
|
||||||
abbrev = 40;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!strcmp(argv[1]+2, "abbrev")) {
|
|
||||||
abbrev = DEFAULT_ABBREV;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* otherwise fallthru */
|
|
||||||
default:
|
|
||||||
usage(ls_tree_usage);
|
|
||||||
}
|
|
||||||
argc--; argv++;
|
|
||||||
}
|
}
|
||||||
/* -d -r should imply -t, but -d by itself should not have to. */
|
/* -d -r should imply -t, but -d by itself should not have to. */
|
||||||
if ( (LS_TREE_ONLY|LS_RECURSIVE) ==
|
if ( (LS_TREE_ONLY|LS_RECURSIVE) ==
|
||||||
((LS_TREE_ONLY|LS_RECURSIVE) & ls_options))
|
((LS_TREE_ONLY|LS_RECURSIVE) & ls_options))
|
||||||
ls_options |= LS_SHOW_TREES;
|
ls_options |= LS_SHOW_TREES;
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 1)
|
||||||
usage(ls_tree_usage);
|
usage_with_options(ls_tree_usage, ls_tree_options);
|
||||||
if (get_sha1(argv[1], sha1))
|
if (get_sha1(argv[0], sha1))
|
||||||
die("Not a valid object name %s", argv[1]);
|
die("Not a valid object name %s", argv[0]);
|
||||||
|
|
||||||
pathspec = get_pathspec(prefix, argv + 2);
|
pathspec = get_pathspec(prefix, argv + 1);
|
||||||
tree = parse_tree_indirect(sha1);
|
tree = parse_tree_indirect(sha1);
|
||||||
if (!tree)
|
if (!tree)
|
||||||
die("not a tree object");
|
die("not a tree object");
|
||||||
|
@ -26,6 +26,7 @@ static struct strbuf charset = STRBUF_INIT;
|
|||||||
static int patch_lines;
|
static int patch_lines;
|
||||||
static struct strbuf **p_hdr_data, **s_hdr_data;
|
static struct strbuf **p_hdr_data, **s_hdr_data;
|
||||||
static int use_scissors;
|
static int use_scissors;
|
||||||
|
static int use_inbody_headers = 1;
|
||||||
|
|
||||||
#define MAX_HDR_PARSED 10
|
#define MAX_HDR_PARSED 10
|
||||||
#define MAX_BOUNDARIES 5
|
#define MAX_BOUNDARIES 5
|
||||||
@ -774,10 +775,17 @@ static int handle_commit_msg(struct strbuf *line)
|
|||||||
strbuf_ltrim(line);
|
strbuf_ltrim(line);
|
||||||
if (!line->len)
|
if (!line->len)
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_inbody_headers && still_looking) {
|
||||||
still_looking = check_header(line, s_hdr_data, 0);
|
still_looking = check_header(line, s_hdr_data, 0);
|
||||||
if (still_looking)
|
if (still_looking)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else
|
||||||
|
/* Only trim the first (blank) line of the commit message
|
||||||
|
* when ignoring in-body headers.
|
||||||
|
*/
|
||||||
|
still_looking = 0;
|
||||||
|
|
||||||
/* normalize the log message to UTF-8. */
|
/* normalize the log message to UTF-8. */
|
||||||
if (metainfo_charset)
|
if (metainfo_charset)
|
||||||
@ -1033,6 +1041,8 @@ int cmd_mailinfo(int argc, const char **argv, const char *prefix)
|
|||||||
use_scissors = 1;
|
use_scissors = 1;
|
||||||
else if (!strcmp(argv[1], "--no-scissors"))
|
else if (!strcmp(argv[1], "--no-scissors"))
|
||||||
use_scissors = 0;
|
use_scissors = 0;
|
||||||
|
else if (!strcmp(argv[1], "--no-inbody-headers"))
|
||||||
|
use_inbody_headers = 0;
|
||||||
else
|
else
|
||||||
usage(mailinfo_usage);
|
usage(mailinfo_usage);
|
||||||
argc--; argv++;
|
argc--; argv++;
|
||||||
|
@ -231,6 +231,8 @@ int cmd_mailsplit(int argc, const char **argv, const char *prefix)
|
|||||||
continue;
|
continue;
|
||||||
} else if ( arg[1] == 'f' ) {
|
} else if ( arg[1] == 'f' ) {
|
||||||
nr = strtol(arg+2, NULL, 10);
|
nr = strtol(arg+2, NULL, 10);
|
||||||
|
} else if ( arg[1] == 'h' ) {
|
||||||
|
usage(git_mailsplit_usage);
|
||||||
} else if ( arg[1] == 'b' && !arg[2] ) {
|
} else if ( arg[1] == 'b' && !arg[2] ) {
|
||||||
allow_bare = 1;
|
allow_bare = 1;
|
||||||
} else if (!strcmp(arg, "--keep-cr")) {
|
} else if (!strcmp(arg, "--keep-cr")) {
|
||||||
|
@ -10,6 +10,9 @@
|
|||||||
#include "git-compat-util.h"
|
#include "git-compat-util.h"
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
|
|
||||||
|
static const char builtin_merge_ours_usage[] =
|
||||||
|
"git merge-ours <base>... -- HEAD <remote>...";
|
||||||
|
|
||||||
static const char *diff_index_args[] = {
|
static const char *diff_index_args[] = {
|
||||||
"diff-index", "--quiet", "--cached", "HEAD", "--", NULL
|
"diff-index", "--quiet", "--cached", "HEAD", "--", NULL
|
||||||
};
|
};
|
||||||
@ -17,6 +20,9 @@ static const char *diff_index_args[] = {
|
|||||||
|
|
||||||
int cmd_merge_ours(int argc, const char **argv, const char *prefix)
|
int cmd_merge_ours(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
|
if (argc == 2 && !strcmp(argv[1], "-h"))
|
||||||
|
usage(builtin_merge_ours_usage);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We need to exit with 2 if the index does not match our HEAD tree,
|
* We need to exit with 2 if the index does not match our HEAD tree,
|
||||||
* because the current index is what we will be committing as the
|
* because the current index is what we will be committing as the
|
||||||
|
@ -33,7 +33,7 @@ int cmd_merge_recursive(int argc, const char **argv, const char *prefix)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (argc < 4)
|
if (argc < 4)
|
||||||
die("Usage: %s <base>... -- <head> <remote> ...", argv[0]);
|
usagef("%s <base>... -- <head> <remote> ...", argv[0]);
|
||||||
|
|
||||||
for (i = 1; i < argc; ++i) {
|
for (i = 1; i < argc; ++i) {
|
||||||
if (!strcmp(argv[i], "--"))
|
if (!strcmp(argv[i], "--"))
|
||||||
|
@ -43,6 +43,7 @@ static const char * const builtin_merge_usage[] = {
|
|||||||
|
|
||||||
static int show_diffstat = 1, option_log, squash;
|
static int show_diffstat = 1, option_log, squash;
|
||||||
static int option_commit = 1, allow_fast_forward = 1;
|
static int option_commit = 1, allow_fast_forward = 1;
|
||||||
|
static int fast_forward_only;
|
||||||
static int allow_trivial = 1, have_message;
|
static int allow_trivial = 1, have_message;
|
||||||
static struct strbuf merge_msg;
|
static struct strbuf merge_msg;
|
||||||
static struct commit_list *remoteheads;
|
static struct commit_list *remoteheads;
|
||||||
@ -166,7 +167,9 @@ static struct option builtin_merge_options[] = {
|
|||||||
OPT_BOOLEAN(0, "commit", &option_commit,
|
OPT_BOOLEAN(0, "commit", &option_commit,
|
||||||
"perform a commit if the merge succeeds (default)"),
|
"perform a commit if the merge succeeds (default)"),
|
||||||
OPT_BOOLEAN(0, "ff", &allow_fast_forward,
|
OPT_BOOLEAN(0, "ff", &allow_fast_forward,
|
||||||
"allow fast forward (default)"),
|
"allow fast-forward (default)"),
|
||||||
|
OPT_BOOLEAN(0, "ff-only", &fast_forward_only,
|
||||||
|
"abort if fast-forward is not possible"),
|
||||||
OPT_CALLBACK('s', "strategy", &use_strategies, "strategy",
|
OPT_CALLBACK('s', "strategy", &use_strategies, "strategy",
|
||||||
"merge strategy to use", option_parse_strategy),
|
"merge strategy to use", option_parse_strategy),
|
||||||
OPT_CALLBACK('m', "message", &merge_msg, "message",
|
OPT_CALLBACK('m', "message", &merge_msg, "message",
|
||||||
@ -264,6 +267,7 @@ static void squash_message(void)
|
|||||||
struct strbuf out = STRBUF_INIT;
|
struct strbuf out = STRBUF_INIT;
|
||||||
struct commit_list *j;
|
struct commit_list *j;
|
||||||
int fd;
|
int fd;
|
||||||
|
struct pretty_print_context ctx = {0};
|
||||||
|
|
||||||
printf("Squash commit -- not updating HEAD\n");
|
printf("Squash commit -- not updating HEAD\n");
|
||||||
fd = open(git_path("SQUASH_MSG"), O_WRONLY | O_CREAT, 0666);
|
fd = open(git_path("SQUASH_MSG"), O_WRONLY | O_CREAT, 0666);
|
||||||
@ -285,13 +289,15 @@ static void squash_message(void)
|
|||||||
if (prepare_revision_walk(&rev))
|
if (prepare_revision_walk(&rev))
|
||||||
die("revision walk setup failed");
|
die("revision walk setup failed");
|
||||||
|
|
||||||
|
ctx.abbrev = rev.abbrev;
|
||||||
|
ctx.date_mode = rev.date_mode;
|
||||||
|
|
||||||
strbuf_addstr(&out, "Squashed commit of the following:\n");
|
strbuf_addstr(&out, "Squashed commit of the following:\n");
|
||||||
while ((commit = get_revision(&rev)) != NULL) {
|
while ((commit = get_revision(&rev)) != NULL) {
|
||||||
strbuf_addch(&out, '\n');
|
strbuf_addch(&out, '\n');
|
||||||
strbuf_addf(&out, "commit %s\n",
|
strbuf_addf(&out, "commit %s\n",
|
||||||
sha1_to_hex(commit->object.sha1));
|
sha1_to_hex(commit->object.sha1));
|
||||||
pretty_print_commit(rev.commit_format, commit, &out, rev.abbrev,
|
pretty_print_commit(rev.commit_format, commit, &out, &ctx);
|
||||||
NULL, NULL, rev.date_mode, 0);
|
|
||||||
}
|
}
|
||||||
if (write(fd, out.buf, out.len) < 0)
|
if (write(fd, out.buf, out.len) < 0)
|
||||||
die_errno("Writing SQUASH_MSG");
|
die_errno("Writing SQUASH_MSG");
|
||||||
@ -840,7 +846,6 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
|||||||
const char *best_strategy = NULL, *wt_strategy = NULL;
|
const char *best_strategy = NULL, *wt_strategy = NULL;
|
||||||
struct commit_list **remotes = &remoteheads;
|
struct commit_list **remotes = &remoteheads;
|
||||||
|
|
||||||
setup_work_tree();
|
|
||||||
if (file_exists(git_path("MERGE_HEAD")))
|
if (file_exists(git_path("MERGE_HEAD")))
|
||||||
die("You have not concluded your merge. (MERGE_HEAD exists)");
|
die("You have not concluded your merge. (MERGE_HEAD exists)");
|
||||||
if (read_cache_unmerged())
|
if (read_cache_unmerged())
|
||||||
@ -874,6 +879,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
|||||||
option_commit = 0;
|
option_commit = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!allow_fast_forward && fast_forward_only)
|
||||||
|
die("You cannot combine --no-ff with --ff-only.");
|
||||||
|
|
||||||
if (!argc)
|
if (!argc)
|
||||||
usage_with_options(builtin_merge_usage,
|
usage_with_options(builtin_merge_usage,
|
||||||
builtin_merge_options);
|
builtin_merge_options);
|
||||||
@ -1013,7 +1021,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
|||||||
hex,
|
hex,
|
||||||
find_unique_abbrev(remoteheads->item->object.sha1,
|
find_unique_abbrev(remoteheads->item->object.sha1,
|
||||||
DEFAULT_ABBREV));
|
DEFAULT_ABBREV));
|
||||||
strbuf_addstr(&msg, "Fast forward");
|
strbuf_addstr(&msg, "Fast-forward");
|
||||||
if (have_message)
|
if (have_message)
|
||||||
strbuf_addstr(&msg,
|
strbuf_addstr(&msg,
|
||||||
" (no commit created; -m option ignored)");
|
" (no commit created; -m option ignored)");
|
||||||
@ -1031,16 +1039,16 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
|||||||
} else if (!remoteheads->next && common->next)
|
} else if (!remoteheads->next && common->next)
|
||||||
;
|
;
|
||||||
/*
|
/*
|
||||||
* We are not doing octopus and not fast forward. Need
|
* We are not doing octopus and not fast-forward. Need
|
||||||
* a real merge.
|
* a real merge.
|
||||||
*/
|
*/
|
||||||
else if (!remoteheads->next && !common->next && option_commit) {
|
else if (!remoteheads->next && !common->next && option_commit) {
|
||||||
/*
|
/*
|
||||||
* We are not doing octopus, not fast forward, and have
|
* We are not doing octopus, not fast-forward, and have
|
||||||
* only one common.
|
* only one common.
|
||||||
*/
|
*/
|
||||||
refresh_cache(REFRESH_QUIET);
|
refresh_cache(REFRESH_QUIET);
|
||||||
if (allow_trivial) {
|
if (allow_trivial && !fast_forward_only) {
|
||||||
/* See if it is really trivial. */
|
/* See if it is really trivial. */
|
||||||
git_committer_info(IDENT_ERROR_ON_NO_NAME);
|
git_committer_info(IDENT_ERROR_ON_NO_NAME);
|
||||||
printf("Trying really trivial in-index merge...\n");
|
printf("Trying really trivial in-index merge...\n");
|
||||||
@ -1079,6 +1087,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fast_forward_only)
|
||||||
|
die("Not possible to fast-forward, aborting.");
|
||||||
|
|
||||||
/* We are going to make a new commit. */
|
/* We are going to make a new commit. */
|
||||||
git_committer_info(IDENT_ERROR_ON_NO_NAME);
|
git_committer_info(IDENT_ERROR_ON_NO_NAME);
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user