mirror of
https://github.com/git/git.git
synced 2026-04-02 13:00:08 +02:00
Merge commit 'j6t/master' into devel
Conflicts: Makefile compat/mingw.c compat/win32mmap.c t/t1301-shared-repo.sh t/t4020-diff-external.sh t/t4129-apply-samemode.sh t/t7005-editor.sh t/test-lib.sh Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This commit is contained in:
@@ -129,3 +129,6 @@ For C programs:
|
|||||||
used in the git core command set (unless your command is clearly
|
used in the git core command set (unless your command is clearly
|
||||||
separate from it, such as an importer to convert random-scm-X
|
separate from it, such as an importer to convert random-scm-X
|
||||||
repositories to git).
|
repositories to git).
|
||||||
|
|
||||||
|
- When we pass <string, length> pair to functions, we should try to
|
||||||
|
pass them in that order.
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ man7dir=$(mandir)/man7
|
|||||||
|
|
||||||
ASCIIDOC=asciidoc
|
ASCIIDOC=asciidoc
|
||||||
ASCIIDOC_EXTRA =
|
ASCIIDOC_EXTRA =
|
||||||
MANPAGE_XSL = callouts.xsl
|
MANPAGE_XSL = manpage-normal.xsl
|
||||||
|
XMLTO_EXTRA =
|
||||||
INSTALL?=install
|
INSTALL?=install
|
||||||
RM ?= rm -f
|
RM ?= rm -f
|
||||||
DOC_REF = origin/man
|
DOC_REF = origin/man
|
||||||
@@ -59,12 +60,47 @@ endif
|
|||||||
-include ../config.mak.autogen
|
-include ../config.mak.autogen
|
||||||
-include ../config.mak
|
-include ../config.mak
|
||||||
|
|
||||||
|
#
|
||||||
|
# For asciidoc ...
|
||||||
|
# -7.1.2, no extra settings are needed.
|
||||||
|
# 8.0-, set ASCIIDOC8.
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# For docbook-xsl ...
|
||||||
|
# -1.68.1, set ASCIIDOC_NO_ROFF? (based on changelog from 1.73.0)
|
||||||
|
# 1.69.0, no extra settings are needed?
|
||||||
|
# 1.69.1-1.71.0, set DOCBOOK_SUPPRESS_SP?
|
||||||
|
# 1.71.1, no extra settings are needed?
|
||||||
|
# 1.72.0, set DOCBOOK_XSL_172.
|
||||||
|
# 1.73.0-, set ASCIIDOC_NO_ROFF
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# If you had been using DOCBOOK_XSL_172 in an attempt to get rid
|
||||||
|
# of 'the ".ft C" problem' in your generated manpages, and you
|
||||||
|
# instead ended up with weird characters around callouts, try
|
||||||
|
# using ASCIIDOC_NO_ROFF instead (it works fine with ASCIIDOC8).
|
||||||
|
#
|
||||||
|
|
||||||
ifdef ASCIIDOC8
|
ifdef ASCIIDOC8
|
||||||
ASCIIDOC_EXTRA += -a asciidoc7compatible
|
ASCIIDOC_EXTRA += -a asciidoc7compatible
|
||||||
endif
|
endif
|
||||||
ifdef DOCBOOK_XSL_172
|
ifdef DOCBOOK_XSL_172
|
||||||
ASCIIDOC_EXTRA += -a docbook-xsl-172
|
ASCIIDOC_EXTRA += -a git-asciidoc-no-roff
|
||||||
MANPAGE_XSL = manpage-1.72.xsl
|
MANPAGE_XSL = manpage-1.72.xsl
|
||||||
|
else
|
||||||
|
ifdef ASCIIDOC_NO_ROFF
|
||||||
|
# docbook-xsl after 1.72 needs the regular XSL, but will not
|
||||||
|
# pass-thru raw roff codes from asciidoc.conf, so turn them off.
|
||||||
|
ASCIIDOC_EXTRA += -a git-asciidoc-no-roff
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
ifdef MAN_BOLD_LITERAL
|
||||||
|
XMLTO_EXTRA += -m manpage-bold-literal.xsl
|
||||||
|
endif
|
||||||
|
ifdef DOCBOOK_SUPPRESS_SP
|
||||||
|
XMLTO_EXTRA += -m manpage-suppress-sp.xsl
|
||||||
endif
|
endif
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -76,6 +112,32 @@ endif
|
|||||||
# yourself - yes, all 6 characters of it!
|
# yourself - yes, all 6 characters of it!
|
||||||
#
|
#
|
||||||
|
|
||||||
|
QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir
|
||||||
|
QUIET_SUBDIR1 =
|
||||||
|
|
||||||
|
ifneq ($(findstring $(MAKEFLAGS),w),w)
|
||||||
|
PRINT_DIR = --no-print-directory
|
||||||
|
else # "make -w"
|
||||||
|
NO_SUBDIR = :
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(findstring $(MAKEFLAGS),s),s)
|
||||||
|
ifndef V
|
||||||
|
QUIET_ASCIIDOC = @echo ' ' ASCIIDOC $@;
|
||||||
|
QUIET_XMLTO = @echo ' ' XMLTO $@;
|
||||||
|
QUIET_DB2TEXI = @echo ' ' DB2TEXI $@;
|
||||||
|
QUIET_MAKEINFO = @echo ' ' MAKEINFO $@;
|
||||||
|
QUIET_DBLATEX = @echo ' ' DBLATEX $@;
|
||||||
|
QUIET_XSLTPROC = @echo ' ' XSLTPROC $@;
|
||||||
|
QUIET_GEN = @echo ' ' GEN $@;
|
||||||
|
QUIET_STDERR = 2> /dev/null
|
||||||
|
QUIET_SUBDIR0 = +@subdir=
|
||||||
|
QUIET_SUBDIR1 = ;$(NO_SUBDIR) echo ' ' SUBDIR $$subdir; \
|
||||||
|
$(MAKE) $(PRINT_DIR) -C $$subdir
|
||||||
|
export V
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
all: html man
|
all: html man
|
||||||
|
|
||||||
html: $(DOC_HTML)
|
html: $(DOC_HTML)
|
||||||
@@ -119,7 +181,7 @@ install-html: html
|
|||||||
sh ./install-webdoc.sh $(DESTDIR)$(htmldir)
|
sh ./install-webdoc.sh $(DESTDIR)$(htmldir)
|
||||||
|
|
||||||
../GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
|
../GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
|
||||||
$(MAKE) -C ../ GIT-VERSION-FILE
|
$(QUIET_SUBDIR0)../ $(QUIET_SUBDIR1) GIT-VERSION-FILE
|
||||||
|
|
||||||
-include ../GIT-VERSION-FILE
|
-include ../GIT-VERSION-FILE
|
||||||
|
|
||||||
@@ -127,8 +189,8 @@ install-html: html
|
|||||||
# Determine "include::" file references in asciidoc files.
|
# Determine "include::" file references in asciidoc files.
|
||||||
#
|
#
|
||||||
doc.dep : $(wildcard *.txt) build-docdep.perl
|
doc.dep : $(wildcard *.txt) build-docdep.perl
|
||||||
$(RM) $@+ $@
|
$(QUIET_GEN)$(RM) $@+ $@ && \
|
||||||
$(PERL_PATH) ./build-docdep.perl >$@+
|
$(PERL_PATH) ./build-docdep.perl >$@+ $(QUIET_STDERR) && \
|
||||||
mv $@+ $@
|
mv $@+ $@
|
||||||
|
|
||||||
-include doc.dep
|
-include doc.dep
|
||||||
@@ -146,91 +208,94 @@ cmds_txt = cmds-ancillaryinterrogators.txt \
|
|||||||
$(cmds_txt): cmd-list.made
|
$(cmds_txt): cmd-list.made
|
||||||
|
|
||||||
cmd-list.made: cmd-list.perl ../command-list.txt $(MAN1_TXT)
|
cmd-list.made: cmd-list.perl ../command-list.txt $(MAN1_TXT)
|
||||||
$(RM) $@
|
$(QUIET_GEN)$(RM) $@ && \
|
||||||
$(PERL_PATH) ./cmd-list.perl ../command-list.txt
|
$(PERL_PATH) ./cmd-list.perl ../command-list.txt $(QUIET_STDERR) && \
|
||||||
date >$@
|
date >$@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) *.xml *.xml+ *.html *.html+ *.1 *.5 *.7
|
$(RM) *.xml *.xml+ *.html *.html+ *.1 *.5 *.7
|
||||||
$(RM) *.texi *.texi+ git.info gitman.info
|
$(RM) *.texi *.texi+ *.texi++ git.info gitman.info
|
||||||
$(RM) howto-index.txt howto/*.html doc.dep
|
$(RM) howto-index.txt howto/*.html doc.dep
|
||||||
$(RM) technical/api-*.html technical/api-index.txt
|
$(RM) technical/api-*.html technical/api-index.txt
|
||||||
$(RM) $(cmds_txt) *.made
|
$(RM) $(cmds_txt) *.made
|
||||||
|
|
||||||
$(MAN_HTML): %.html : %.txt
|
$(MAN_HTML): %.html : %.txt
|
||||||
$(RM) $@+ $@
|
$(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
|
||||||
$(ASCIIDOC) -b xhtml11 -d manpage -f asciidoc.conf \
|
$(ASCIIDOC) -b xhtml11 -d manpage -f asciidoc.conf \
|
||||||
$(ASCIIDOC_EXTRA) -agit_version=$(GIT_VERSION) -o $@+ $<
|
$(ASCIIDOC_EXTRA) -agit_version=$(GIT_VERSION) -o $@+ $< && \
|
||||||
mv $@+ $@
|
mv $@+ $@
|
||||||
|
|
||||||
%.1 %.5 %.7 : %.xml
|
%.1 %.5 %.7 : %.xml
|
||||||
$(RM) $@
|
$(QUIET_XMLTO)$(RM) $@ && \
|
||||||
xmlto -m $(MANPAGE_XSL) man $<
|
xmlto -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $<
|
||||||
|
|
||||||
%.xml : %.txt
|
%.xml : %.txt
|
||||||
$(RM) $@+ $@
|
$(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
|
||||||
$(ASCIIDOC) -b docbook -d manpage -f asciidoc.conf \
|
$(ASCIIDOC) -b docbook -d manpage -f asciidoc.conf \
|
||||||
$(ASCIIDOC_EXTRA) -agit_version=$(GIT_VERSION) -o $@+ $<
|
$(ASCIIDOC_EXTRA) -agit_version=$(GIT_VERSION) -o $@+ $< && \
|
||||||
mv $@+ $@
|
mv $@+ $@
|
||||||
|
|
||||||
user-manual.xml: user-manual.txt user-manual.conf
|
user-manual.xml: user-manual.txt user-manual.conf
|
||||||
$(ASCIIDOC) -b docbook -d book $<
|
$(QUIET_ASCIIDOC)$(ASCIIDOC) -b docbook -d book $<
|
||||||
|
|
||||||
technical/api-index.txt: technical/api-index-skel.txt \
|
technical/api-index.txt: technical/api-index-skel.txt \
|
||||||
technical/api-index.sh $(patsubst %,%.txt,$(API_DOCS))
|
technical/api-index.sh $(patsubst %,%.txt,$(API_DOCS))
|
||||||
cd technical && sh ./api-index.sh
|
$(QUIET_GEN)cd technical && sh ./api-index.sh
|
||||||
|
|
||||||
$(patsubst %,%.html,$(API_DOCS) technical/api-index): %.html : %.txt
|
$(patsubst %,%.html,$(API_DOCS) technical/api-index): %.html : %.txt
|
||||||
$(ASCIIDOC) -b xhtml11 -f asciidoc.conf \
|
$(QUIET_ASCIIDOC)$(ASCIIDOC) -b xhtml11 -f asciidoc.conf \
|
||||||
$(ASCIIDOC_EXTRA) -agit_version=$(GIT_VERSION) $*.txt
|
$(ASCIIDOC_EXTRA) -agit_version=$(GIT_VERSION) $*.txt
|
||||||
|
|
||||||
XSLT = docbook.xsl
|
XSLT = docbook.xsl
|
||||||
XSLTOPTS = --xinclude --stringparam html.stylesheet docbook-xsl.css
|
XSLTOPTS = --xinclude --stringparam html.stylesheet docbook-xsl.css
|
||||||
|
|
||||||
user-manual.html: user-manual.xml
|
user-manual.html: user-manual.xml
|
||||||
xsltproc $(XSLTOPTS) -o $@ $(XSLT) $<
|
$(QUIET_XSLTPROC)xsltproc $(XSLTOPTS) -o $@ $(XSLT) $<
|
||||||
|
|
||||||
git.info: user-manual.texi
|
git.info: user-manual.texi
|
||||||
$(MAKEINFO) --no-split -o $@ user-manual.texi
|
$(QUIET_MAKEINFO)$(MAKEINFO) --no-split -o $@ user-manual.texi
|
||||||
|
|
||||||
user-manual.texi: user-manual.xml
|
user-manual.texi: user-manual.xml
|
||||||
$(RM) $@+ $@
|
$(QUIET_DB2TEXI)$(RM) $@+ $@ && \
|
||||||
$(DOCBOOK2X_TEXI) user-manual.xml --encoding=UTF-8 --to-stdout | \
|
$(DOCBOOK2X_TEXI) user-manual.xml --encoding=UTF-8 --to-stdout >$@++ && \
|
||||||
$(PERL_PATH) fix-texi.perl >$@+
|
$(PERL_PATH) fix-texi.perl <$@++ >$@+ && \
|
||||||
|
rm $@++ && \
|
||||||
mv $@+ $@
|
mv $@+ $@
|
||||||
|
|
||||||
user-manual.pdf: user-manual.xml
|
user-manual.pdf: user-manual.xml
|
||||||
$(RM) $@+ $@
|
$(QUIET_DBLATEX)$(RM) $@+ $@ && \
|
||||||
$(DBLATEX) -o $@+ -p /etc/asciidoc/dblatex/asciidoc-dblatex.xsl -s /etc/asciidoc/dblatex/asciidoc-dblatex.sty $<
|
$(DBLATEX) -o $@+ -p /etc/asciidoc/dblatex/asciidoc-dblatex.xsl -s /etc/asciidoc/dblatex/asciidoc-dblatex.sty $< && \
|
||||||
mv $@+ $@
|
mv $@+ $@
|
||||||
|
|
||||||
gitman.texi: $(MAN_XML) cat-texi.perl
|
gitman.texi: $(MAN_XML) cat-texi.perl
|
||||||
$(RM) $@+ $@
|
$(QUIET_DB2TEXI)$(RM) $@+ $@ && \
|
||||||
($(foreach xml,$(MAN_XML),$(DOCBOOK2X_TEXI) --encoding=UTF-8 \
|
($(foreach xml,$(MAN_XML),$(DOCBOOK2X_TEXI) --encoding=UTF-8 \
|
||||||
--to-stdout $(xml);)) | $(PERL_PATH) cat-texi.perl $@ >$@+
|
--to-stdout $(xml) &&) true) > $@++ && \
|
||||||
|
$(PERL_PATH) cat-texi.perl $@ <$@++ >$@+ && \
|
||||||
|
rm $@++ && \
|
||||||
mv $@+ $@
|
mv $@+ $@
|
||||||
|
|
||||||
gitman.info: gitman.texi
|
gitman.info: gitman.texi
|
||||||
$(MAKEINFO) --no-split --no-validate $*.texi
|
$(QUIET_MAKEINFO)$(MAKEINFO) --no-split --no-validate $*.texi
|
||||||
|
|
||||||
$(patsubst %.txt,%.texi,$(MAN_TXT)): %.texi : %.xml
|
$(patsubst %.txt,%.texi,$(MAN_TXT)): %.texi : %.xml
|
||||||
$(RM) $@+ $@
|
$(QUIET_DB2TEXI)$(RM) $@+ $@ && \
|
||||||
$(DOCBOOK2X_TEXI) --to-stdout $*.xml >$@+
|
$(DOCBOOK2X_TEXI) --to-stdout $*.xml >$@+ && \
|
||||||
mv $@+ $@
|
mv $@+ $@
|
||||||
|
|
||||||
howto-index.txt: howto-index.sh $(wildcard howto/*.txt)
|
howto-index.txt: howto-index.sh $(wildcard howto/*.txt)
|
||||||
$(RM) $@+ $@
|
$(QUIET_GEN)$(RM) $@+ $@ && \
|
||||||
sh ./howto-index.sh $(wildcard howto/*.txt) >$@+
|
sh ./howto-index.sh $(wildcard howto/*.txt) >$@+ && \
|
||||||
mv $@+ $@
|
mv $@+ $@
|
||||||
|
|
||||||
$(patsubst %,%.html,$(ARTICLES)) : %.html : %.txt
|
$(patsubst %,%.html,$(ARTICLES)) : %.html : %.txt
|
||||||
$(ASCIIDOC) -b xhtml11 $*.txt
|
$(QUIET_ASCIIDOC)$(ASCIIDOC) -b xhtml11 $*.txt
|
||||||
|
|
||||||
WEBDOC_DEST = /pub/software/scm/git/docs
|
WEBDOC_DEST = /pub/software/scm/git/docs
|
||||||
|
|
||||||
$(patsubst %.txt,%.html,$(wildcard howto/*.txt)): %.html : %.txt
|
$(patsubst %.txt,%.html,$(wildcard howto/*.txt)): %.html : %.txt
|
||||||
$(RM) $@+ $@
|
$(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
|
||||||
sed -e '1,/^$$/d' $< | $(ASCIIDOC) -b xhtml11 - >$@+
|
sed -e '1,/^$$/d' $< | $(ASCIIDOC) -b xhtml11 - >$@+ && \
|
||||||
mv $@+ $@
|
mv $@+ $@
|
||||||
|
|
||||||
install-webdoc : html
|
install-webdoc : html
|
||||||
|
|||||||
45
Documentation/RelNotes-1.6.2.2.txt
Normal file
45
Documentation/RelNotes-1.6.2.2.txt
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
GIT v1.6.2.2 Release Notes
|
||||||
|
==========================
|
||||||
|
|
||||||
|
Fixes since v1.6.2.1
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
* A longstanding confusing description of what --pickaxe option of
|
||||||
|
git-diff does has been clarified in the documentation.
|
||||||
|
|
||||||
|
* "git-blame -S" did not quite work near the commits that were given
|
||||||
|
on the command line correctly.
|
||||||
|
|
||||||
|
* "git diff --pickaxe-regexp" did not count overlapping matches
|
||||||
|
correctly.
|
||||||
|
|
||||||
|
* "git diff" did not feed files in work-tree representation to external
|
||||||
|
diff and textconv.
|
||||||
|
|
||||||
|
* "git-fetch" in a repository that was not cloned from anywhere said
|
||||||
|
it cannot find 'origin', which was hard to understand for new people.
|
||||||
|
|
||||||
|
* "git-format-patch --numbered-files --stdout" did not have to die of
|
||||||
|
incompatible options; it now simply ignores --numbered-files as no files
|
||||||
|
are produced anyway.
|
||||||
|
|
||||||
|
* "git-ls-files --deleted" did not work well with GIT_DIR&GIT_WORK_TREE.
|
||||||
|
|
||||||
|
* "git-read-tree A B C..." without -m option has been broken for a long
|
||||||
|
time.
|
||||||
|
|
||||||
|
* git-send-email ignored --in-reply-to when --no-thread was given.
|
||||||
|
|
||||||
|
* 'git-submodule add' did not tolerate extra slashes and ./ in the path it
|
||||||
|
accepted from the command line; it now is more lenient.
|
||||||
|
|
||||||
|
* git-svn misbehaved when the project contained a path that began with
|
||||||
|
two dashes.
|
||||||
|
|
||||||
|
* import-zips script (in contrib) did not compute the common directory
|
||||||
|
prefix correctly.
|
||||||
|
|
||||||
|
* miscompilation of negated enum constants by old gcc (2.9) affected the
|
||||||
|
codepaths to spawn subprocesses.
|
||||||
|
|
||||||
|
Many small documentation updates are included as well.
|
||||||
@@ -22,6 +22,13 @@ branch pointed at by its HEAD, gets a large warning. You can choose what
|
|||||||
should happen upon such a push by setting the configuration variable
|
should happen upon such a push by setting the configuration variable
|
||||||
receive.denyDeleteCurrent in the receiving repository.
|
receive.denyDeleteCurrent in the receiving repository.
|
||||||
|
|
||||||
|
When the user does not tell "git push" what to push, it has always
|
||||||
|
pushed matching refs. For some people it is unexpected, and a new
|
||||||
|
configuration variable push.default has been introduced to allow
|
||||||
|
changing a different default behaviour. To advertise the new feature,
|
||||||
|
a big warning is issued if this is not configured and a git push without
|
||||||
|
arguments is attempted.
|
||||||
|
|
||||||
|
|
||||||
Updates since v1.6.2
|
Updates since v1.6.2
|
||||||
--------------------
|
--------------------
|
||||||
@@ -30,8 +37,21 @@ Updates since v1.6.2
|
|||||||
|
|
||||||
(performance)
|
(performance)
|
||||||
|
|
||||||
|
* many uses of lstat(2) in the codepath for "git checkout" have been
|
||||||
|
optimized out.
|
||||||
|
|
||||||
(usability, bells and whistles)
|
(usability, bells and whistles)
|
||||||
|
|
||||||
|
* rsync:/path/to/repo can be used to run git over rsync for local
|
||||||
|
repositories. It may not be useful in practice; meant primarily for
|
||||||
|
testing.
|
||||||
|
|
||||||
|
* http transport learned to prompt and use password when fetching from or
|
||||||
|
pushing to http://user@host.xz/ URL.
|
||||||
|
|
||||||
|
* (msysgit) progress output that is sent over the sideband protocol can
|
||||||
|
be handled appropriately in Windows console.
|
||||||
|
|
||||||
* "--pretty=<style>" option to the log family of commands can now be
|
* "--pretty=<style>" option to the log family of commands can now be
|
||||||
spelled as "--format=<style>". In addition, --format=%formatstring
|
spelled as "--format=<style>". In addition, --format=%formatstring
|
||||||
is a short-hand for --pretty=tformat:%formatstring.
|
is a short-hand for --pretty=tformat:%formatstring.
|
||||||
@@ -42,6 +62,10 @@ Updates since v1.6.2
|
|||||||
with the 'edit' action in git-add -i/-p, you can abort the editor to
|
with the 'edit' action in git-add -i/-p, you can abort the editor to
|
||||||
tell git not to apply it.
|
tell git not to apply it.
|
||||||
|
|
||||||
|
* The number of commits shown in "you are ahead/behind your upstream"
|
||||||
|
messages given by "git checkout" and "git status" used to count merge
|
||||||
|
commits; now it doesn't.
|
||||||
|
|
||||||
* git-archive learned --output=<file> option.
|
* git-archive learned --output=<file> option.
|
||||||
|
|
||||||
* git-bisect shows not just the number of remaining commits whose goodness
|
* git-bisect shows not just the number of remaining commits whose goodness
|
||||||
@@ -57,11 +81,19 @@ Updates since v1.6.2
|
|||||||
|
|
||||||
* git-clone runs post-checkout hook when run without --no-checkout.
|
* git-clone runs post-checkout hook when run without --no-checkout.
|
||||||
|
|
||||||
|
* git-fast-export choked when seeing a tag that does not point at commit.
|
||||||
|
|
||||||
* git-format-patch can be told to use attachment with a new configuration,
|
* git-format-patch can be told to use attachment with a new configuration,
|
||||||
format.attach.
|
format.attach.
|
||||||
|
|
||||||
* git-format-patch can be told to produce deep or shallow message threads.
|
* git-format-patch can be told to produce deep or shallow message threads.
|
||||||
|
|
||||||
|
* git-format-patch learned format.headers configuration to add extra
|
||||||
|
header fields to the output. This behaviour is similar to the existing
|
||||||
|
--add-header=<header> option of the command.
|
||||||
|
|
||||||
|
* git-grep learned to highlight the found substrings in color.
|
||||||
|
|
||||||
* git-imap-send learned to work around Thunderbird's inability to easily
|
* git-imap-send learned to work around Thunderbird's inability to easily
|
||||||
disable format=flowed with a new configuration, imap.preformattedHTML.
|
disable format=flowed with a new configuration, imap.preformattedHTML.
|
||||||
|
|
||||||
@@ -71,6 +103,13 @@ Updates since v1.6.2
|
|||||||
|
|
||||||
* git-rebase can be told to report diffstat with the --stat option.
|
* git-rebase can be told to report diffstat with the --stat option.
|
||||||
|
|
||||||
|
* Output from git-remote command has been vastly improved.
|
||||||
|
|
||||||
|
* git-repack (invoked from git-gc) did not work as nicely as it should in
|
||||||
|
a repository that borrows objects from neighbours via alternates
|
||||||
|
mechanism especially when some packs are marked with the ".keep" flag
|
||||||
|
to prevent them from being repacked.
|
||||||
|
|
||||||
* git-send-email learned --confirm option to review the Cc: list before
|
* git-send-email learned --confirm option to review the Cc: list before
|
||||||
sending the messages out.
|
sending the messages out.
|
||||||
|
|
||||||
@@ -78,9 +117,18 @@ Updates since v1.6.2
|
|||||||
|
|
||||||
* Test scripts can be run under valgrind.
|
* Test scripts can be run under valgrind.
|
||||||
|
|
||||||
|
* Test scripts can be run with installed git.
|
||||||
|
|
||||||
* Makefile learned 'coverage' option to run the test suites with
|
* Makefile learned 'coverage' option to run the test suites with
|
||||||
coverage tracking enabled.
|
coverage tracking enabled.
|
||||||
|
|
||||||
|
* Building the manpages with docbook-xsl between 1.69.1 and 1.71.1 now
|
||||||
|
requires setting DOCBOOK_SUPPRESS_SP to work around a docbook-xsl bug.
|
||||||
|
This workaround used to be enabled by default, but causes problems
|
||||||
|
with newer versions of docbook-xsl. In addition, there are a few more
|
||||||
|
knobs you can tweak to work around issues with various versions of the
|
||||||
|
docbook-xsl package. See comments in Documentation/Makefile for details.
|
||||||
|
|
||||||
Fixes since v1.6.2
|
Fixes since v1.6.2
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
@@ -90,15 +138,14 @@ release, unless otherwise noted.
|
|||||||
Here are fixes that this release has, but have not been backported to
|
Here are fixes that this release has, but have not been backported to
|
||||||
v1.6.2.X series.
|
v1.6.2.X series.
|
||||||
|
|
||||||
* 'git-submodule add' did not tolerate extra slashes and ./ in the
|
* The initial checkout did not read the attributes from the .gitattribute
|
||||||
path it accepted from the command line; it now is more lenient
|
file that is being checked out.
|
||||||
(if needed, backport by merging db75ada).
|
|
||||||
|
|
||||||
* git-gc spent excessive amount of time to decide if an object appears
|
* git-gc spent excessive amount of time to decide if an object appears
|
||||||
in a locally existing pack (if needed, backport by merging 69e020a).
|
in a locally existing pack (if needed, backport by merging 69e020a).
|
||||||
|
|
||||||
---
|
---
|
||||||
exec >/var/tmp/1
|
exec >/var/tmp/1
|
||||||
O=v1.6.2.1-135-g7d65c21
|
O=v1.6.2.2-403-g8130949
|
||||||
echo O=$(git describe master)
|
echo O=$(git describe master)
|
||||||
git shortlog --no-merges $O..master ^maint
|
git shortlog --no-merges $O..master ^maint
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ ifdef::backend-docbook[]
|
|||||||
endif::backend-docbook[]
|
endif::backend-docbook[]
|
||||||
|
|
||||||
ifdef::backend-docbook[]
|
ifdef::backend-docbook[]
|
||||||
ifndef::docbook-xsl-172[]
|
ifndef::git-asciidoc-no-roff[]
|
||||||
# "unbreak" docbook-xsl v1.68 for manpages. v1.69 works with or without this.
|
# "unbreak" docbook-xsl v1.68 for manpages. v1.69 works with or without this.
|
||||||
# v1.72 breaks with this because it replaces dots not in roff requests.
|
# v1.72 breaks with this because it replaces dots not in roff requests.
|
||||||
[listingblock]
|
[listingblock]
|
||||||
@@ -42,16 +42,16 @@ ifdef::doctype-manpage[]
|
|||||||
endif::doctype-manpage[]
|
endif::doctype-manpage[]
|
||||||
</literallayout>
|
</literallayout>
|
||||||
{title#}</example>
|
{title#}</example>
|
||||||
endif::docbook-xsl-172[]
|
endif::git-asciidoc-no-roff[]
|
||||||
|
|
||||||
ifdef::docbook-xsl-172[]
|
ifdef::git-asciidoc-no-roff[]
|
||||||
ifdef::doctype-manpage[]
|
ifdef::doctype-manpage[]
|
||||||
# The following two small workarounds insert a simple paragraph after screen
|
# The following two small workarounds insert a simple paragraph after screen
|
||||||
[listingblock]
|
[listingblock]
|
||||||
<example><title>{title}</title>
|
<example><title>{title}</title>
|
||||||
<screen>
|
<literallayout>
|
||||||
|
|
|
|
||||||
</screen><simpara></simpara>
|
</literallayout><simpara></simpara>
|
||||||
{title#}</example>
|
{title#}</example>
|
||||||
|
|
||||||
[verseblock]
|
[verseblock]
|
||||||
@@ -59,10 +59,11 @@ ifdef::doctype-manpage[]
|
|||||||
{title%}<literallayout{id? id="{id}"}>
|
{title%}<literallayout{id? id="{id}"}>
|
||||||
{title#}<literallayout>
|
{title#}<literallayout>
|
||||||
|
|
|
|
||||||
</literallayout><simpara></simpara>
|
</literallayout>
|
||||||
{title#}</para></formalpara>
|
{title#}</para></formalpara>
|
||||||
|
{title%}<simpara></simpara>
|
||||||
endif::doctype-manpage[]
|
endif::doctype-manpage[]
|
||||||
endif::docbook-xsl-172[]
|
endif::git-asciidoc-no-roff[]
|
||||||
endif::backend-docbook[]
|
endif::backend-docbook[]
|
||||||
|
|
||||||
ifdef::doctype-manpage[]
|
ifdef::doctype-manpage[]
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ of lines before or after the line given by <start>.
|
|||||||
Show raw timestamp (Default: off).
|
Show raw timestamp (Default: off).
|
||||||
|
|
||||||
-S <revs-file>::
|
-S <revs-file>::
|
||||||
Use revs from revs-file instead of calling linkgit:git-rev-list[1].
|
Use revisions from revs-file instead of calling linkgit:git-rev-list[1].
|
||||||
|
|
||||||
--reverse::
|
--reverse::
|
||||||
Walk history forward instead of backward. Instead of showing
|
Walk history forward instead of backward. Instead of showing
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
<!-- callout.xsl: converts asciidoc callouts to man page format -->
|
|
||||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
|
||||||
<xsl:template match="co">
|
|
||||||
<xsl:value-of select="concat('\fB(',substring-after(@id,'-'),')\fR')"/>
|
|
||||||
</xsl:template>
|
|
||||||
<xsl:template match="calloutlist">
|
|
||||||
<xsl:text>.sp </xsl:text>
|
|
||||||
<xsl:apply-templates/>
|
|
||||||
<xsl:text> </xsl:text>
|
|
||||||
</xsl:template>
|
|
||||||
<xsl:template match="callout">
|
|
||||||
<xsl:value-of select="concat('\fB',substring-after(@arearefs,'-'),'. \fR')"/>
|
|
||||||
<xsl:apply-templates/>
|
|
||||||
<xsl:text>.br </xsl:text>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
<!-- sorry, this is not about callouts, but attempts to work around
|
|
||||||
spurious .sp at the tail of the line docbook stylesheets seem to add -->
|
|
||||||
<xsl:template match="simpara">
|
|
||||||
<xsl:variable name="content">
|
|
||||||
<xsl:apply-templates/>
|
|
||||||
</xsl:variable>
|
|
||||||
<xsl:value-of select="normalize-space($content)"/>
|
|
||||||
<xsl:if test="not(ancestor::authorblurb) and
|
|
||||||
not(ancestor::personblurb)">
|
|
||||||
<xsl:text> </xsl:text>
|
|
||||||
</xsl:if>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
</xsl:stylesheet>
|
|
||||||
@@ -25,7 +25,7 @@ blank lines are ignored.
|
|||||||
The file consists of sections and variables. A section begins with
|
The file consists of sections and variables. A section begins with
|
||||||
the name of the section in square brackets and continues until the next
|
the name of the section in square brackets and continues until the next
|
||||||
section begins. Section names are not case sensitive. Only alphanumeric
|
section begins. Section names are not case sensitive. Only alphanumeric
|
||||||
characters, '`-`' and '`.`' are allowed in section names. Each variable
|
characters, `-` and `.` are allowed in section names. Each variable
|
||||||
must belong to some section, which means that there must be section
|
must belong to some section, which means that there must be section
|
||||||
header before first setting of a variable.
|
header before first setting of a variable.
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ in the section header, like in example below:
|
|||||||
--------
|
--------
|
||||||
|
|
||||||
Subsection names can contain any characters except newline (doublequote
|
Subsection names can contain any characters except newline (doublequote
|
||||||
'`"`' and backslash have to be escaped as '`\"`' and '`\\`',
|
`"` and backslash have to be escaped as `\"` and `\\`,
|
||||||
respectively) and are case sensitive. Section header cannot span multiple
|
respectively) and are case sensitive. Section header cannot span multiple
|
||||||
lines. Variables may belong directly to a section or to a given subsection.
|
lines. Variables may belong directly to a section or to a given subsection.
|
||||||
You can have `[section]` if you have `[section "subsection"]`, but you
|
You can have `[section]` if you have `[section "subsection"]`, but you
|
||||||
@@ -53,7 +53,7 @@ All the other lines are recognized as setting variables, in the form
|
|||||||
'name = value'. If there is no equal sign on the line, the entire line
|
'name = value'. If there is no equal sign on the line, the entire line
|
||||||
is taken as 'name' and the variable is recognized as boolean "true".
|
is taken as 'name' and the variable is recognized as boolean "true".
|
||||||
The variable names are case-insensitive and only alphanumeric
|
The variable names are case-insensitive and only alphanumeric
|
||||||
characters and '`-`' are allowed. There can be more than one value
|
characters and `-` are allowed. There can be more than one value
|
||||||
for a given variable; we say then that variable is multivalued.
|
for a given variable; we say then that variable is multivalued.
|
||||||
|
|
||||||
Leading and trailing whitespace in a variable value is discarded.
|
Leading and trailing whitespace in a variable value is discarded.
|
||||||
@@ -69,15 +69,15 @@ String values may be entirely or partially enclosed in double quotes.
|
|||||||
You need to enclose variable value in double quotes if you want to
|
You need to enclose variable value in double quotes if you want to
|
||||||
preserve leading or trailing whitespace, or if variable value contains
|
preserve leading or trailing whitespace, or if variable value contains
|
||||||
beginning of comment characters (if it contains '#' or ';').
|
beginning of comment characters (if it contains '#' or ';').
|
||||||
Double quote '`"`' and backslash '`\`' characters in variable value must
|
Double quote `"` and backslash `\` characters in variable value must
|
||||||
be escaped: use '`\"`' for '`"`' and '`\\`' for '`\`'.
|
be escaped: use `\"` for `"` and `\\` for `\`.
|
||||||
|
|
||||||
The following escape sequences (beside '`\"`' and '`\\`') are recognized:
|
The following escape sequences (beside `\"` and `\\`) are recognized:
|
||||||
'`\n`' for newline character (NL), '`\t`' for horizontal tabulation (HT, TAB)
|
`\n` for newline character (NL), `\t` for horizontal tabulation (HT, TAB)
|
||||||
and '`\b`' for backspace (BS). No other char escape sequence, nor octal
|
and `\b` for backspace (BS). No other char escape sequence, nor octal
|
||||||
char sequences are valid.
|
char sequences are valid.
|
||||||
|
|
||||||
Variable value ending in a '`\`' is continued on the next line in the
|
Variable value ending in a `\` is continued on the next line in the
|
||||||
customary UNIX fashion.
|
customary UNIX fashion.
|
||||||
|
|
||||||
Some variables may require special value format.
|
Some variables may require special value format.
|
||||||
@@ -221,6 +221,11 @@ core.gitProxy::
|
|||||||
Can be overridden by the 'GIT_PROXY_COMMAND' environment variable
|
Can be overridden by the 'GIT_PROXY_COMMAND' environment variable
|
||||||
(which always applies universally, without the special "for"
|
(which always applies universally, without the special "for"
|
||||||
handling).
|
handling).
|
||||||
|
+
|
||||||
|
The special string `none` can be used as the proxy command to
|
||||||
|
specify that no proxy be used for a given domain pattern.
|
||||||
|
This is useful for excluding servers inside a firewall from
|
||||||
|
proxy use, while defaulting to a common proxy for external domains.
|
||||||
|
|
||||||
core.ignoreStat::
|
core.ignoreStat::
|
||||||
If true, commands which modify both the working tree and the index
|
If true, commands which modify both the working tree and the index
|
||||||
@@ -382,9 +387,9 @@ core.pager::
|
|||||||
to override git's default settings this way, you need
|
to override git's default settings this way, you need
|
||||||
to be explicit. For example, to disable the S option
|
to be explicit. For example, to disable the S option
|
||||||
in a backward compatible manner, set `core.pager`
|
in a backward compatible manner, set `core.pager`
|
||||||
to "`less -+$LESS -FRX`". This will be passed to the
|
to `less -+$LESS -FRX`. This will be passed to the
|
||||||
shell by git, which will translate the final command to
|
shell by git, which will translate the final command to
|
||||||
"`LESS=FRSX less -+FRSX -FRX`".
|
`LESS=FRSX less -+FRSX -FRX`.
|
||||||
|
|
||||||
core.whitespace::
|
core.whitespace::
|
||||||
A comma separated list of common whitespace problems to
|
A comma separated list of common whitespace problems to
|
||||||
@@ -468,10 +473,14 @@ branch.autosetuprebase::
|
|||||||
This option defaults to never.
|
This option defaults to never.
|
||||||
|
|
||||||
branch.<name>.remote::
|
branch.<name>.remote::
|
||||||
When in branch <name>, it tells 'git-fetch' which remote to fetch.
|
When in branch <name>, it tells 'git-fetch' and 'git-push' which
|
||||||
If this option is not given, 'git-fetch' defaults to remote "origin".
|
remote to fetch from/push to. It defaults to `origin` if no remote is
|
||||||
|
configured. `origin` is also used if you are not on any branch.
|
||||||
|
|
||||||
branch.<name>.merge::
|
branch.<name>.merge::
|
||||||
|
Defines, together with branch.<name>.remote, the upstream branch
|
||||||
|
for the given branch. It tells 'git-fetch'/'git-pull' which
|
||||||
|
branch to merge from.
|
||||||
When in branch <name>, it tells 'git-fetch' the default
|
When in branch <name>, it tells 'git-fetch' the default
|
||||||
refspec to be marked for merging in FETCH_HEAD. The value is
|
refspec to be marked for merging in FETCH_HEAD. The value is
|
||||||
handled like the remote part of a refspec, and must match a
|
handled like the remote part of a refspec, and must match a
|
||||||
@@ -548,6 +557,25 @@ color.diff.<slot>::
|
|||||||
whitespace errors). The values of these variables may be specified as
|
whitespace errors). The values of these variables may be specified as
|
||||||
in color.branch.<slot>.
|
in color.branch.<slot>.
|
||||||
|
|
||||||
|
color.grep::
|
||||||
|
When set to `always`, always highlight matches. When `false` (or
|
||||||
|
`never`), never. When set to `true` or `auto`, use color only
|
||||||
|
when the output is written to the terminal. Defaults to `false`.
|
||||||
|
|
||||||
|
color.grep.external::
|
||||||
|
The string value of this variable is passed to an external 'grep'
|
||||||
|
command as a command line option if match highlighting is turned
|
||||||
|
on. If set to an empty string, no option is passed at all,
|
||||||
|
turning off coloring for external 'grep' calls; this is the default.
|
||||||
|
For GNU grep, set it to `--color=always` to highlight matches even
|
||||||
|
when a pager is used.
|
||||||
|
|
||||||
|
color.grep.match::
|
||||||
|
Use customized color for matches. The value of this variable
|
||||||
|
may be specified as in color.branch.<slot>. It is passed using
|
||||||
|
the environment variables 'GREP_COLOR' and 'GREP_COLORS' when
|
||||||
|
calling an external 'grep'.
|
||||||
|
|
||||||
color.interactive::
|
color.interactive::
|
||||||
When set to `always`, always use colors for interactive prompts
|
When set to `always`, always use colors for interactive prompts
|
||||||
and displays (such as those used by "git-add --interactive").
|
and displays (such as those used by "git-add --interactive").
|
||||||
@@ -1161,7 +1189,7 @@ pager.<cmd>::
|
|||||||
particular git subcommand when writing to a tty. If
|
particular git subcommand when writing to a tty. If
|
||||||
`\--paginate` or `\--no-pager` is specified on the command line,
|
`\--paginate` or `\--no-pager` is specified on the command line,
|
||||||
it takes precedence over this option. To disable pagination for
|
it takes precedence over this option. To disable pagination for
|
||||||
all commands, set `core.pager` or 'GIT_PAGER' to "`cat`".
|
all commands, set `core.pager` or `GIT_PAGER` to `cat`.
|
||||||
|
|
||||||
pull.octopus::
|
pull.octopus::
|
||||||
The default merge strategy to use when pulling multiple branches
|
The default merge strategy to use when pulling multiple branches
|
||||||
@@ -1170,6 +1198,19 @@ pull.octopus::
|
|||||||
pull.twohead::
|
pull.twohead::
|
||||||
The default merge strategy to use when pulling a single branch.
|
The default merge strategy to use when pulling a single branch.
|
||||||
|
|
||||||
|
push.default::
|
||||||
|
Defines the action git push should take if no refspec is given
|
||||||
|
on the command line, no refspec is configured in the remote, and
|
||||||
|
no refspec is implied by any of the options given on the command
|
||||||
|
line. Possible values are:
|
||||||
|
+
|
||||||
|
* `nothing` do not push anything.
|
||||||
|
* `matching` push all matching branches.
|
||||||
|
All branches having the same name in both ends are considered to be
|
||||||
|
matching. This is the default.
|
||||||
|
* `tracking` push the current branch to the branch it is tracking.
|
||||||
|
* `current` push the current branch to a branch of the same name.
|
||||||
|
|
||||||
rebase.stat::
|
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.
|
||||||
|
|||||||
@@ -176,7 +176,10 @@ override configuration settings.
|
|||||||
number.
|
number.
|
||||||
|
|
||||||
-S<string>::
|
-S<string>::
|
||||||
Look for differences that contain the change in <string>.
|
Look for differences that introduce or remove an instance of
|
||||||
|
<string>. Note that this is different than the string simply
|
||||||
|
appearing in diff output; see the 'pickaxe' entry in
|
||||||
|
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
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ Use a tarball as a starting point for a new repository.::
|
|||||||
------------
|
------------
|
||||||
$ tar zxf frotz.tar.gz
|
$ tar zxf frotz.tar.gz
|
||||||
$ cd frotz
|
$ cd frotz
|
||||||
$ git-init
|
$ git init
|
||||||
$ git add . <1>
|
$ git add . <1>
|
||||||
$ git commit -m "import of frotz source tree."
|
$ git commit -m "import of frotz source tree."
|
||||||
$ git tag v2.43 <2>
|
$ git tag v2.43 <2>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ prepended to the filenames in the archive.
|
|||||||
|
|
||||||
'git-archive' behaves differently when given a tree ID versus when
|
'git-archive' behaves differently when given a tree ID versus when
|
||||||
given a commit ID or tag ID. In the first case the current time is
|
given a commit ID or tag ID. In the first case the current time is
|
||||||
used as modification time of each file in the archive. In the latter
|
used as the modification time of each file in the archive. In the latter
|
||||||
case the commit time as recorded in the referenced commit object is
|
case the commit time as recorded in the referenced commit object is
|
||||||
used instead. Additionally the commit ID is stored in a global
|
used instead. Additionally the commit ID is stored in a global
|
||||||
extended pax header if the tar format is used; it can be extracted
|
extended pax header if the tar format is used; it can be extracted
|
||||||
@@ -52,11 +52,11 @@ OPTIONS
|
|||||||
Write the archive to <file> instead of stdout.
|
Write the archive to <file> instead of stdout.
|
||||||
|
|
||||||
<extra>::
|
<extra>::
|
||||||
This can be any options that the archiver backend understand.
|
This can be any options that the archiver backend understands.
|
||||||
See next section.
|
See next section.
|
||||||
|
|
||||||
--remote=<repo>::
|
--remote=<repo>::
|
||||||
Instead of making a tar archive from local repository,
|
Instead of making a tar archive from the local repository,
|
||||||
retrieve a tar archive from a remote repository.
|
retrieve a tar archive from a remote repository.
|
||||||
|
|
||||||
--exec=<git-upload-archive>::
|
--exec=<git-upload-archive>::
|
||||||
@@ -109,7 +109,7 @@ EXAMPLES
|
|||||||
git archive --format=tar --prefix=junk/ HEAD | (cd /var/tmp/ && tar xf -)::
|
git archive --format=tar --prefix=junk/ HEAD | (cd /var/tmp/ && tar xf -)::
|
||||||
|
|
||||||
Create a tar archive that contains the contents of the
|
Create a tar archive that contains the contents of the
|
||||||
latest commit on the current branch, and extracts it in
|
latest commit on the current branch, and extract it in the
|
||||||
`/var/tmp/junk` directory.
|
`/var/tmp/junk` directory.
|
||||||
|
|
||||||
git archive --format=tar --prefix=git-1.4.0/ v1.4.0 | gzip >git-1.4.0.tar.gz::
|
git archive --format=tar --prefix=git-1.4.0/ v1.4.0 | gzip >git-1.4.0.tar.gz::
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ git-bisect(1)
|
|||||||
|
|
||||||
NAME
|
NAME
|
||||||
----
|
----
|
||||||
git-bisect - Find the change that introduced a bug by binary search
|
git-bisect - Find by binary search the change that introduced a bug
|
||||||
|
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
@@ -39,7 +39,8 @@ help" or "git bisect -h" to get a long usage description.
|
|||||||
Basic bisect commands: start, bad, good
|
Basic bisect commands: start, bad, good
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
The way you use it is:
|
Using the Linux kernel tree as an example, basic use of the bisect
|
||||||
|
command is as follows:
|
||||||
|
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
$ git bisect start
|
$ git bisect start
|
||||||
@@ -48,61 +49,63 @@ $ git bisect good v2.6.13-rc2 # v2.6.13-rc2 was the last version
|
|||||||
# tested that was good
|
# tested that was good
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
When you give at least one bad and one good versions, it will bisect
|
When you have specified at least one bad and one good version, the
|
||||||
the revision tree and say something like:
|
command bisects the revision tree and outputs something similar to
|
||||||
|
the following:
|
||||||
|
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
Bisecting: 675 revisions left to test after this
|
Bisecting: 675 revisions left to test after this
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
and check out the state in the middle. Now, compile that kernel, and
|
The state in the middle of the set of revisions is then checked out.
|
||||||
boot it. Now, let's say that this booted kernel works fine, then just
|
You would now compile that kernel and boot it. If the booted kernel
|
||||||
do
|
works correctly, you would then issue the following command:
|
||||||
|
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
$ git bisect good # this one is good
|
$ git bisect good # this one is good
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
which will now say
|
The output of this command would be something similar to the following:
|
||||||
|
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
Bisecting: 337 revisions left to test after this
|
Bisecting: 337 revisions left to test after this
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
and you continue along, compiling that one, testing it, and depending
|
You keep repeating this process, compiling the tree, testing it, and
|
||||||
on whether it is good or bad, you say "git bisect good" or "git bisect
|
depending on whether it is good or bad issuing the command "git bisect good"
|
||||||
bad", and ask for the next bisection.
|
or "git bisect bad" to ask for the next bisection.
|
||||||
|
|
||||||
Until you have no more left, and you'll have been left with the first
|
Eventually there will be no more revisions left to bisect, and you
|
||||||
bad kernel rev in "refs/bisect/bad".
|
will have been left with the first bad kernel revision in "refs/bisect/bad".
|
||||||
|
|
||||||
Bisect reset
|
Bisect reset
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
Oh, and then after you want to reset to the original head, do a
|
To return to the original head after a bisect session, issue the
|
||||||
|
following command:
|
||||||
|
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
$ git bisect reset
|
$ git bisect reset
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
to get back to the original branch, instead of being on the bisection
|
This resets the tree to the original branch instead of being on the
|
||||||
commit ("git bisect start" will do that for you too, actually: it will
|
bisection commit ("git bisect start" will also do that, as it resets
|
||||||
reset the bisection state).
|
the bisection state).
|
||||||
|
|
||||||
Bisect visualize
|
Bisect visualize
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
During the bisection process, you can say
|
To see the currently remaining suspects in 'gitk', issue the following
|
||||||
|
command during the bisection process:
|
||||||
|
|
||||||
------------
|
------------
|
||||||
$ git bisect visualize
|
$ git bisect visualize
|
||||||
------------
|
------------
|
||||||
|
|
||||||
to see the currently remaining suspects in 'gitk'. `visualize` is a bit
|
`view` may also be used as a synonym for `visualize`.
|
||||||
too long to type and `view` is provided as a synonym.
|
|
||||||
|
|
||||||
If 'DISPLAY' environment variable is not set, 'git log' is used
|
If the 'DISPLAY' environment variable is not set, 'git log' is used
|
||||||
instead. You can even give command line options such as `-p` and
|
instead. You can also give command line options such as `-p` and
|
||||||
`--stat`.
|
`--stat`.
|
||||||
|
|
||||||
------------
|
------------
|
||||||
@@ -112,57 +115,58 @@ $ git bisect view --stat
|
|||||||
Bisect log and bisect replay
|
Bisect log and bisect replay
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
The good/bad input is logged, and
|
After having marked revisions as good or bad, issue the following
|
||||||
|
command to show what has been done so far:
|
||||||
|
|
||||||
------------
|
------------
|
||||||
$ git bisect log
|
$ git bisect log
|
||||||
------------
|
------------
|
||||||
|
|
||||||
shows what you have done so far. You can truncate its output somewhere
|
If you discover that you made a mistake in specifying the status of a
|
||||||
and save it in a file, and run
|
revision, you can save the output of this command to a file, edit it to
|
||||||
|
remove the incorrect entries, and then issue the following commands to
|
||||||
|
return to a corrected state:
|
||||||
|
|
||||||
------------
|
------------
|
||||||
|
$ git bisect reset
|
||||||
$ git bisect replay that-file
|
$ git bisect replay that-file
|
||||||
------------
|
------------
|
||||||
|
|
||||||
if you find later you made a mistake telling good/bad about a
|
Avoiding testing a commit
|
||||||
revision.
|
|
||||||
|
|
||||||
Avoiding to test a commit
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
If in a middle of bisect session, you know what the bisect suggested
|
If, in the middle of a bisect session, you know that the next suggested
|
||||||
to try next is not a good one to test (e.g. the change the commit
|
revision is not a good one to test (e.g. the change the commit
|
||||||
introduces is known not to work in your environment and you know it
|
introduces is known not to work in your environment and you know it
|
||||||
does not have anything to do with the bug you are chasing), you may
|
does not have anything to do with the bug you are chasing), you may
|
||||||
want to find a near-by commit and try that instead.
|
want to find a nearby commit and try that instead.
|
||||||
|
|
||||||
It goes something like this:
|
For example:
|
||||||
|
|
||||||
------------
|
------------
|
||||||
$ git bisect good/bad # previous round was good/bad.
|
$ git bisect good/bad # previous round was good or bad.
|
||||||
Bisecting: 337 revisions left to test after this
|
Bisecting: 337 revisions left to test after this
|
||||||
$ git bisect visualize # oops, that is uninteresting.
|
$ git bisect visualize # oops, that is uninteresting.
|
||||||
$ git reset --hard HEAD~3 # try 3 revs before what
|
$ git reset --hard HEAD~3 # try 3 revisions before what
|
||||||
# was suggested
|
# was suggested
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Then compile and test the one you chose to try. After that, tell
|
Then compile and test the chosen revision, and afterwards mark
|
||||||
bisect what the result was as usual.
|
the revision as good or bad in the usual manner.
|
||||||
|
|
||||||
Bisect skip
|
Bisect skip
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
Instead of choosing by yourself a nearby commit, you may just want git
|
Instead of choosing by yourself a nearby commit, you can ask git
|
||||||
to do it for you using:
|
to do it for you by issuing the command:
|
||||||
|
|
||||||
------------
|
------------
|
||||||
$ git bisect skip # Current version cannot be tested
|
$ git bisect skip # Current version cannot be tested
|
||||||
------------
|
------------
|
||||||
|
|
||||||
But computing the commit to test may be slower afterwards and git may
|
But computing the commit to test may be slower afterwards and git may
|
||||||
eventually not be able to tell the first bad among a bad and one or
|
eventually not be able to tell the first bad commit among a bad commit
|
||||||
more "skip"ped commits.
|
and one or more skipped commits.
|
||||||
|
|
||||||
You can even skip a range of commits, instead of just one commit,
|
You can even skip a range of commits, instead of just one commit,
|
||||||
using the "'<commit1>'..'<commit2>'" notation. For example:
|
using the "'<commit1>'..'<commit2>'" notation. For example:
|
||||||
@@ -171,33 +175,34 @@ using the "'<commit1>'..'<commit2>'" notation. For example:
|
|||||||
$ git bisect skip v2.5..v2.6
|
$ git bisect skip v2.5..v2.6
|
||||||
------------
|
------------
|
||||||
|
|
||||||
would mean that no commit between `v2.5` excluded and `v2.6` included
|
This tells the bisect process that no commit after `v2.5`, up to and
|
||||||
can be tested.
|
including `v2.6`, should be tested.
|
||||||
|
|
||||||
Note that if you want to also skip the first commit of a range you can
|
Note that if you also want to skip the first commit of the range you
|
||||||
use something like:
|
would issue the command:
|
||||||
|
|
||||||
------------
|
------------
|
||||||
$ git bisect skip v2.5 v2.5..v2.6
|
$ git bisect skip v2.5 v2.5..v2.6
|
||||||
------------
|
------------
|
||||||
|
|
||||||
and the commit pointed to by `v2.5` will be skipped too.
|
This tells the bisect process that the commits between `v2.5` included
|
||||||
|
and `v2.6` included should be skipped.
|
||||||
|
|
||||||
|
|
||||||
Cutting down bisection by giving more parameters to bisect start
|
Cutting down bisection by giving more parameters to bisect start
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
You can further cut down the number of trials if you know what part of
|
You can further cut down the number of trials, if you know what part of
|
||||||
the tree is involved in the problem you are tracking down, by giving
|
the tree is involved in the problem you are tracking down, by specifying
|
||||||
paths parameters when you say `bisect start`, like this:
|
path parameters when issuing the `bisect start` command:
|
||||||
|
|
||||||
------------
|
------------
|
||||||
$ git bisect start -- arch/i386 include/asm-i386
|
$ git bisect start -- arch/i386 include/asm-i386
|
||||||
------------
|
------------
|
||||||
|
|
||||||
If you know beforehand more than one good commits, you can narrow the
|
If you know beforehand more than one good commit, you can narrow the
|
||||||
bisect space down without doing the whole tree checkout every time you
|
bisect space down by specifying all of the good commits immediately after
|
||||||
give good commits. You give the bad revision immediately after `start`
|
the bad commit when issuing the `bisect start` command:
|
||||||
and then you give all the good revisions you have:
|
|
||||||
|
|
||||||
------------
|
------------
|
||||||
$ git bisect start v2.6.20-rc6 v2.6.20-rc4 v2.6.20-rc1 --
|
$ git bisect start v2.6.20-rc6 v2.6.20-rc4 v2.6.20-rc1 --
|
||||||
@@ -209,38 +214,38 @@ Bisect run
|
|||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
If you have a script that can tell if the current source code is good
|
If you have a script that can tell if the current source code is good
|
||||||
or bad, you can automatically bisect using:
|
or bad, you can bisect by issuing the command:
|
||||||
|
|
||||||
------------
|
------------
|
||||||
$ git bisect run my_script arguments
|
$ git bisect run my_script arguments
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Note that the "run" script (`my_script` in the above example) should
|
Note that the script (`my_script` in the above example) should
|
||||||
exit with code 0 in case the current source code is good. Exit with a
|
exit with code 0 if the current source code is good, and exit with a
|
||||||
code between 1 and 127 (inclusive), except 125, if the current
|
code between 1 and 127 (inclusive), except 125, if the current
|
||||||
source code is bad.
|
source code is bad.
|
||||||
|
|
||||||
Any other exit code will abort the automatic bisect process. (A
|
Any other exit code will abort the bisect process. It should be noted
|
||||||
program that does "exit(-1)" leaves $? = 255, see exit(3) manual page,
|
that a program that terminates via "exit(-1)" leaves $? = 255, (see the
|
||||||
the value is chopped with "& 0377".)
|
exit(3) manual page), as the value is chopped with "& 0377".
|
||||||
|
|
||||||
The special exit code 125 should be used when the current source code
|
The special exit code 125 should be used when the current source code
|
||||||
cannot be tested. If the "run" script exits with this code, the current
|
cannot be tested. If the script exits with this code, the current
|
||||||
revision will be skipped, see `git bisect skip` above.
|
revision will be skipped (see `git bisect skip` above).
|
||||||
|
|
||||||
You may often find that during bisect you want to have near-constant
|
You may often find that during a bisect session you want to have
|
||||||
tweaks (e.g., s/#define DEBUG 0/#define DEBUG 1/ in a header file, or
|
temporary modifications (e.g. s/#define DEBUG 0/#define DEBUG 1/ in a
|
||||||
"revision that does not have this commit needs this patch applied to
|
header file, or "revision that does not have this commit needs this
|
||||||
work around other problem this bisection is not interested in")
|
patch applied to work around another problem this bisection is not
|
||||||
applied to the revision being tested.
|
interested in") applied to the revision being tested.
|
||||||
|
|
||||||
To cope with such a situation, after the inner 'git bisect' finds the
|
To cope with such a situation, after the inner 'git bisect' finds the
|
||||||
next revision to test, with the "run" script, you can apply that tweak
|
next revision to test, the script can apply the patch
|
||||||
before compiling, run the real test, and after the test decides if the
|
before compiling, run the real test, and afterwards decide if the
|
||||||
revision (possibly with the needed tweaks) passed the test, rewind the
|
revision (possibly with the needed patch) passed the test and then
|
||||||
tree to the pristine state. Finally the "run" script can exit with
|
rewind the tree to the pristine state. Finally the script should exit
|
||||||
the status of the real test to let the "git bisect run" command loop to
|
with the status of the real test to let the "git bisect run" command loop
|
||||||
determine the outcome.
|
determine the eventual outcome of the bisect session.
|
||||||
|
|
||||||
EXAMPLES
|
EXAMPLES
|
||||||
--------
|
--------
|
||||||
@@ -264,39 +269,39 @@ $ git bisect run make test # "make test" builds and tests
|
|||||||
------------
|
------------
|
||||||
$ cat ~/test.sh
|
$ cat ~/test.sh
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
make || exit 125 # this "skip"s broken builds
|
make || exit 125 # this skips broken builds
|
||||||
make test # "make test" runs the test suite
|
make test # "make test" runs the test suite
|
||||||
$ git bisect start v1.3 v1.1 -- # v1.3 is bad, v1.1 is good
|
$ git bisect start v1.3 v1.1 -- # v1.3 is bad, v1.1 is good
|
||||||
$ git bisect run ~/test.sh
|
$ git bisect run ~/test.sh
|
||||||
------------
|
------------
|
||||||
+
|
+
|
||||||
Here we use a "test.sh" custom script. In this script, if "make"
|
Here we use a "test.sh" custom script. In this script, if "make"
|
||||||
fails, we "skip" the current commit.
|
fails, we skip the current commit.
|
||||||
+
|
+
|
||||||
It's safer to use a custom script outside the repo to prevent
|
It is safer to use a custom script outside the repository to prevent
|
||||||
interactions between the bisect, make and test processes and the
|
interactions between the bisect, make and test processes and the
|
||||||
script.
|
script.
|
||||||
+
|
+
|
||||||
And "make test" should "exit 0", if the test suite passes, and
|
"make test" should "exit 0", if the test suite passes, and
|
||||||
"exit 1" (for example) otherwise.
|
"exit 1" otherwise.
|
||||||
|
|
||||||
* Automatically bisect a broken test case:
|
* Automatically bisect a broken test case:
|
||||||
+
|
+
|
||||||
------------
|
------------
|
||||||
$ cat ~/test.sh
|
$ cat ~/test.sh
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
make || exit 125 # this "skip"s broken builds
|
make || exit 125 # this skips broken builds
|
||||||
~/check_test_case.sh # does the test case passes ?
|
~/check_test_case.sh # does the test case passes ?
|
||||||
$ git bisect start HEAD HEAD~10 -- # culprit is among the last 10
|
$ git bisect start HEAD HEAD~10 -- # culprit is among the last 10
|
||||||
$ git bisect run ~/test.sh
|
$ git bisect run ~/test.sh
|
||||||
------------
|
------------
|
||||||
+
|
+
|
||||||
Here "check_test_case.sh" should "exit 0", if the test case passes,
|
Here "check_test_case.sh" should "exit 0" if the test case passes,
|
||||||
and "exit 1" (for example) otherwise.
|
and "exit 1" otherwise.
|
||||||
+
|
+
|
||||||
It's safer if both "test.sh" and "check_test_case.sh" scripts are
|
It is safer if both "test.sh" and "check_test_case.sh" scripts are
|
||||||
outside the repo to prevent interactions between the bisect, make and
|
outside the repository to prevent interactions between the bisect,
|
||||||
test processes and the scripts.
|
make and test processes and the scripts.
|
||||||
|
|
||||||
* Automatically bisect a broken test suite:
|
* Automatically bisect a broken test suite:
|
||||||
+
|
+
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ DESCRIPTION
|
|||||||
Annotates each line in the given file with information from the revision which
|
Annotates each line in the given file with information from the revision which
|
||||||
last modified the line. Optionally, start annotating from the given revision.
|
last modified the line. Optionally, start annotating from the given revision.
|
||||||
|
|
||||||
Also it can limit the range of lines annotated.
|
The command can also limit the range of lines annotated.
|
||||||
|
|
||||||
This report doesn't tell you anything about lines which have been deleted or
|
The report does not tell you anything about lines which have been deleted or
|
||||||
replaced; you need to use a tool such as 'git-diff' or the "pickaxe"
|
replaced; you need to use a tool such as 'git-diff' or the "pickaxe"
|
||||||
interface briefly mentioned in the following paragraph.
|
interface briefly mentioned in the following paragraph.
|
||||||
|
|
||||||
@@ -48,26 +48,26 @@ include::blame-options.txt[]
|
|||||||
lines between files (see `-C`) and lines moved within a
|
lines between files (see `-C`) and lines moved within a
|
||||||
file (see `-M`). The first number listed is the score.
|
file (see `-M`). The first number listed is the score.
|
||||||
This is the number of alphanumeric characters detected
|
This is the number of alphanumeric characters detected
|
||||||
to be moved between or within files. This must be above
|
as having been moved between or within files. This must be above
|
||||||
a certain threshold for 'git-blame' to consider those lines
|
a certain threshold for 'git-blame' to consider those lines
|
||||||
of code to have been moved.
|
of code to have been moved.
|
||||||
|
|
||||||
-f::
|
-f::
|
||||||
--show-name::
|
--show-name::
|
||||||
Show filename in the original commit. By default
|
Show the filename in the original commit. By default
|
||||||
filename is shown if there is any line that came from a
|
the filename is shown if there is any line that came from a
|
||||||
file with different name, due to rename detection.
|
file with a different name, due to rename detection.
|
||||||
|
|
||||||
-n::
|
-n::
|
||||||
--show-number::
|
--show-number::
|
||||||
Show line number in the original commit (Default: off).
|
Show the line number in the original commit (Default: off).
|
||||||
|
|
||||||
-s::
|
-s::
|
||||||
Suppress author name and timestamp from the output.
|
Suppress the author name and timestamp from the output.
|
||||||
|
|
||||||
-w::
|
-w::
|
||||||
Ignore whitespace when comparing parent's version and
|
Ignore whitespace when comparing the parent's version and
|
||||||
child's to find where the lines came from.
|
the child's to find where the lines came from.
|
||||||
|
|
||||||
|
|
||||||
THE PORCELAIN FORMAT
|
THE PORCELAIN FORMAT
|
||||||
@@ -79,17 +79,17 @@ header at the minimum has the first line which has:
|
|||||||
- 40-byte SHA-1 of the commit the line is attributed to;
|
- 40-byte SHA-1 of the commit the line is attributed to;
|
||||||
- the line number of the line in the original file;
|
- the line number of the line in the original file;
|
||||||
- the line number of the line in the final file;
|
- the line number of the line in the final file;
|
||||||
- on a line that starts a group of line from a different
|
- on a line that starts a group of lines from a different
|
||||||
commit than the previous one, the number of lines in this
|
commit than the previous one, the number of lines in this
|
||||||
group. On subsequent lines this field is absent.
|
group. On subsequent lines this field is absent.
|
||||||
|
|
||||||
This header line is followed by the following information
|
This header line is followed by the following information
|
||||||
at least once for each commit:
|
at least once for each commit:
|
||||||
|
|
||||||
- author name ("author"), email ("author-mail"), time
|
- the author name ("author"), email ("author-mail"), time
|
||||||
("author-time"), and timezone ("author-tz"); similarly
|
("author-time"), and timezone ("author-tz"); similarly
|
||||||
for committer.
|
for committer.
|
||||||
- filename in the commit the line is attributed to.
|
- the filename in the commit that the line is attributed to.
|
||||||
- the first line of the commit log message ("summary").
|
- the first line of the commit log message ("summary").
|
||||||
|
|
||||||
The contents of the actual line is output after the above
|
The contents of the actual line is output after the above
|
||||||
@@ -100,23 +100,23 @@ header elements later.
|
|||||||
SPECIFYING RANGES
|
SPECIFYING RANGES
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
Unlike 'git-blame' and 'git-annotate' in older git, the extent
|
Unlike 'git-blame' and 'git-annotate' in older versions of git, the extent
|
||||||
of annotation can be limited to both line ranges and revision
|
of the annotation can be limited to both line ranges and revision
|
||||||
ranges. When you are interested in finding the origin for
|
ranges. When you are interested in finding the origin for
|
||||||
ll. 40-60 for file `foo`, you can use `-L` option like these
|
lines 40-60 for file `foo`, you can use the `-L` option like so
|
||||||
(they mean the same thing -- both ask for 21 lines starting at
|
(they mean the same thing -- both ask for 21 lines starting at
|
||||||
line 40):
|
line 40):
|
||||||
|
|
||||||
git blame -L 40,60 foo
|
git blame -L 40,60 foo
|
||||||
git blame -L 40,+21 foo
|
git blame -L 40,+21 foo
|
||||||
|
|
||||||
Also you can use regular expression to specify the line range.
|
Also you can use a regular expression to specify the line range:
|
||||||
|
|
||||||
git blame -L '/^sub hello {/,/^}$/' foo
|
git blame -L '/^sub hello {/,/^}$/' foo
|
||||||
|
|
||||||
would limit the annotation to the body of `hello` subroutine.
|
which limits the annotation to the body of the `hello` subroutine.
|
||||||
|
|
||||||
When you are not interested in changes older than the version
|
When you are not interested in changes older than version
|
||||||
v2.6.18, or changes older than 3 weeks, you can use revision
|
v2.6.18, or changes older than 3 weeks, you can use revision
|
||||||
range specifiers similar to 'git-rev-list':
|
range specifiers similar to 'git-rev-list':
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ commit v2.6.18 or the most recent commit that is more than 3
|
|||||||
weeks old in the above example) are blamed for that range
|
weeks old in the above example) are blamed for that range
|
||||||
boundary commit.
|
boundary commit.
|
||||||
|
|
||||||
A particularly useful way is to see if an added file have lines
|
A particularly useful way is to see if an added file has lines
|
||||||
created by copy-and-paste from existing files. Sometimes this
|
created by copy-and-paste from existing files. Sometimes this
|
||||||
indicates that the developer was being sloppy and did not
|
indicates that the developer was being sloppy and did not
|
||||||
refactor the code properly. You can first find the commit that
|
refactor the code properly. You can first find the commit that
|
||||||
@@ -162,26 +162,26 @@ annotated.
|
|||||||
+
|
+
|
||||||
Line numbers count from 1.
|
Line numbers count from 1.
|
||||||
|
|
||||||
. The first time that commit shows up in the stream, it has various
|
. The first time that a commit shows up in the stream, it has various
|
||||||
other information about it printed out with a one-word tag at the
|
other information about it printed out with a one-word tag at the
|
||||||
beginning of each line about that "extended commit info" (author,
|
beginning of each line describing the extra commit information (author,
|
||||||
email, committer, dates, summary etc).
|
email, committer, dates, summary, etc.).
|
||||||
|
|
||||||
. Unlike Porcelain format, the filename information is always
|
. Unlike the Porcelain format, the filename information is always
|
||||||
given and terminates the entry:
|
given and terminates the entry:
|
||||||
|
|
||||||
"filename" <whitespace-quoted-filename-goes-here>
|
"filename" <whitespace-quoted-filename-goes-here>
|
||||||
+
|
+
|
||||||
and thus it's really quite easy to parse for some line- and word-oriented
|
and thus it is really quite easy to parse for some line- and word-oriented
|
||||||
parser (which should be quite natural for most scripting languages).
|
parser (which should be quite natural for most scripting languages).
|
||||||
+
|
+
|
||||||
[NOTE]
|
[NOTE]
|
||||||
For people who do parsing: to make it more robust, just ignore any
|
For people who do parsing: to make it more robust, just ignore any
|
||||||
lines in between the first and last one ("<sha1>" and "filename" lines)
|
lines between the first and last one ("<sha1>" and "filename" lines)
|
||||||
where you don't recognize the tag-words (or care about that particular
|
where you do not recognize the tag words (or care about that particular
|
||||||
one) at the beginning of the "extended information" lines. That way, if
|
one) at the beginning of the "extended information" lines. That way, if
|
||||||
there is ever added information (like the commit encoding or extended
|
there is ever added information (like the commit encoding or extended
|
||||||
commit commentary), a blame viewer won't ever care.
|
commit commentary), a blame viewer will not care.
|
||||||
|
|
||||||
|
|
||||||
MAPPING AUTHORS
|
MAPPING AUTHORS
|
||||||
|
|||||||
@@ -18,19 +18,19 @@ SYNOPSIS
|
|||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
With no arguments, existing branches are listed, the current branch will
|
With no arguments, existing branches are listed and the current branch will
|
||||||
be highlighted with an asterisk. Option `-r` causes the remote-tracking
|
be highlighted with an asterisk. Option `-r` causes the remote-tracking
|
||||||
branches to be listed, and option `-a` shows both.
|
branches to be listed, and option `-a` shows both.
|
||||||
|
|
||||||
With `--contains`, shows only the branches that contains the named commit
|
With `--contains`, shows only the branches that contain the named commit
|
||||||
(in other words, the branches whose tip commits are descendant of the
|
(in other words, the branches whose tip commits are descendants of the
|
||||||
named commit). With `--merged`, only branches merged into the named
|
named commit). With `--merged`, only branches merged into the named
|
||||||
commit (i.e. the branches whose tip commits are reachable from the named
|
commit (i.e. the branches whose tip commits are reachable from the named
|
||||||
commit) will be listed. With `--no-merged` only branches not merged into
|
commit) will be listed. With `--no-merged` only branches not merged into
|
||||||
the named commit will be listed. Missing <commit> argument defaults to
|
the named commit will be listed. If the <commit> argument is missing it
|
||||||
'HEAD' (i.e. the tip of the current branch).
|
defaults to 'HEAD' (i.e. the tip of the current branch).
|
||||||
|
|
||||||
In its second form, a new branch named <branchname> will be created.
|
In the command's second form, a new branch named <branchname> will be created.
|
||||||
It will start out with a head equal to the one given as <start-point>.
|
It will start out with a head equal to the one given as <start-point>.
|
||||||
If no <start-point> is given, the branch will be created with a head
|
If no <start-point> is given, the branch will be created with a head
|
||||||
equal to that of the currently checked out branch.
|
equal to that of the currently checked out branch.
|
||||||
@@ -57,9 +57,9 @@ has a reflog then the reflog will also be deleted.
|
|||||||
|
|
||||||
Use -r together with -d to delete remote-tracking branches. Note, that it
|
Use -r together with -d to delete remote-tracking branches. Note, that it
|
||||||
only makes sense to delete remote-tracking branches if they no longer exist
|
only makes sense to delete remote-tracking branches if they no longer exist
|
||||||
in remote repository or if 'git-fetch' was configured not to fetch
|
in the remote repository or if 'git-fetch' was configured not to fetch
|
||||||
them again. See also 'prune' subcommand of linkgit:git-remote[1] for way to
|
them again. See also the 'prune' subcommand of linkgit:git-remote[1] for a
|
||||||
clean up all obsolete remote-tracking branches.
|
way to clean up all obsolete remote-tracking branches.
|
||||||
|
|
||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
@@ -76,14 +76,14 @@ OPTIONS
|
|||||||
based sha1 expressions such as "<branchname>@\{yesterday}".
|
based sha1 expressions such as "<branchname>@\{yesterday}".
|
||||||
|
|
||||||
-f::
|
-f::
|
||||||
Force the creation of a new branch even if it means deleting
|
Reset <branchname> to <startpoint> if <branchname> exists
|
||||||
a branch that already exists with the same name.
|
already. Without `-f` 'git-branch' refuses to change an existing branch.
|
||||||
|
|
||||||
-m::
|
-m::
|
||||||
Move/rename a branch and the corresponding reflog.
|
Move/rename a branch and the corresponding reflog.
|
||||||
|
|
||||||
-M::
|
-M::
|
||||||
Move/rename a branch even if the new branchname already exists.
|
Move/rename a branch even if the new branch name already exists.
|
||||||
|
|
||||||
--color::
|
--color::
|
||||||
Color branches to highlight current, local, and remote branches.
|
Color branches to highlight current, local, and remote branches.
|
||||||
@@ -103,17 +103,17 @@ OPTIONS
|
|||||||
Show sha1 and commit subject line for each head.
|
Show sha1 and commit subject line for each head.
|
||||||
|
|
||||||
--abbrev=<length>::
|
--abbrev=<length>::
|
||||||
Alter minimum display length for sha1 in output listing,
|
Alter the sha1's minimum display length in the output listing.
|
||||||
default value is 7.
|
The default value is 7.
|
||||||
|
|
||||||
--no-abbrev::
|
--no-abbrev::
|
||||||
Display the full sha1s in output listing rather than abbreviating them.
|
Display the full sha1s in the output listing rather than abbreviating them.
|
||||||
|
|
||||||
--track::
|
--track::
|
||||||
When creating a new branch, set up configuration so that 'git-pull'
|
When creating a new branch, set up the configuration so that 'git-pull'
|
||||||
will automatically retrieve data from the start point, which must be
|
will automatically retrieve data from the start point, which must be
|
||||||
a branch. Use this if you always pull from the same upstream branch
|
a branch. Use this if you always pull from the same upstream branch
|
||||||
into the new branch, and if you don't want to use "git pull
|
into the new branch, and if you do not want to use "git pull
|
||||||
<repository> <refspec>" explicitly. This behavior is the default
|
<repository> <refspec>" explicitly. This behavior is the default
|
||||||
when the start point is a remote branch. Set the
|
when the start point is a remote branch. Set the
|
||||||
branch.autosetupmerge configuration variable to `false` if you want
|
branch.autosetupmerge configuration variable to `false` if you want
|
||||||
@@ -149,13 +149,13 @@ OPTIONS
|
|||||||
|
|
||||||
<newbranch>::
|
<newbranch>::
|
||||||
The new name for an existing branch. The same restrictions as for
|
The new name for an existing branch. The same restrictions as for
|
||||||
<branchname> applies.
|
<branchname> apply.
|
||||||
|
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
--------
|
--------
|
||||||
|
|
||||||
Start development off of a known tag::
|
Start development from a known tag::
|
||||||
+
|
+
|
||||||
------------
|
------------
|
||||||
$ git clone git://git.kernel.org/pub/scm/.../linux-2.6 my2.6
|
$ git clone git://git.kernel.org/pub/scm/.../linux-2.6 my2.6
|
||||||
@@ -167,7 +167,7 @@ $ git checkout my2.6.14
|
|||||||
<1> This step and the next one could be combined into a single step with
|
<1> This step and the next one could be combined into a single step with
|
||||||
"checkout -b my2.6.14 v2.6.14".
|
"checkout -b my2.6.14 v2.6.14".
|
||||||
|
|
||||||
Delete unneeded branch::
|
Delete an unneeded branch::
|
||||||
+
|
+
|
||||||
------------
|
------------
|
||||||
$ git clone git://git.kernel.org/.../git.git my.git
|
$ git clone git://git.kernel.org/.../git.git my.git
|
||||||
@@ -176,21 +176,21 @@ $ git branch -d -r origin/todo origin/html origin/man <1>
|
|||||||
$ git branch -D test <2>
|
$ git branch -D test <2>
|
||||||
------------
|
------------
|
||||||
+
|
+
|
||||||
<1> Delete remote-tracking branches "todo", "html", "man". Next 'fetch' or
|
<1> Delete the remote-tracking branches "todo", "html" and "man". The next
|
||||||
'pull' will create them again unless you configure them not to. See
|
'fetch' or 'pull' will create them again unless you configure them not to.
|
||||||
linkgit:git-fetch[1].
|
See linkgit:git-fetch[1].
|
||||||
<2> Delete "test" branch even if the "master" branch (or whichever branch is
|
<2> Delete the "test" branch even if the "master" branch (or whichever branch
|
||||||
currently checked out) does not have all commits from test branch.
|
is currently checked out) does not have all commits from the test branch.
|
||||||
|
|
||||||
|
|
||||||
Notes
|
Notes
|
||||||
-----
|
-----
|
||||||
|
|
||||||
If you are creating a branch that you want to immediately checkout, it's
|
If you are creating a branch that you want to checkout immediately, it is
|
||||||
easier to use the git checkout command with its `-b` option to create
|
easier to use the git checkout command with its `-b` option to create
|
||||||
a branch and check it out with a single command.
|
a branch and check it out with a single command.
|
||||||
|
|
||||||
The options `--contains`, `--merged` and `--no-merged` serves three related
|
The options `--contains`, `--merged` and `--no-merged` serve three related
|
||||||
but different purposes:
|
but different purposes:
|
||||||
|
|
||||||
- `--contains <commit>` is used to find all branches which will need
|
- `--contains <commit>` is used to find all branches which will need
|
||||||
|
|||||||
@@ -19,13 +19,13 @@ DESCRIPTION
|
|||||||
|
|
||||||
Some workflows require that one or more branches of development on one
|
Some workflows require that one or more branches of development on one
|
||||||
machine be replicated on another machine, but the two machines cannot
|
machine be replicated on another machine, but the two machines cannot
|
||||||
be directly connected so the interactive git protocols (git, ssh,
|
be directly connected, and therefore the interactive git protocols (git,
|
||||||
rsync, http) cannot be used. This command provides support for
|
ssh, rsync, http) cannot be used. This command provides support for
|
||||||
'git-fetch' and 'git-pull' to operate by packaging objects and references
|
'git-fetch' and 'git-pull' to operate by packaging objects and references
|
||||||
in an archive at the originating machine, then importing those into
|
in an archive at the originating machine, then importing those into
|
||||||
another repository using 'git-fetch' and 'git-pull'
|
another repository using 'git-fetch' and 'git-pull'
|
||||||
after moving the archive by some means (i.e., by sneakernet). As no
|
after moving the archive by some means (i.e., by sneakernet). As no
|
||||||
direct connection between repositories exists, the user must specify a
|
direct connection between the repositories exists, the user must specify a
|
||||||
basis for the bundle that is held by the destination repository: the
|
basis for the bundle that is held by the destination repository: the
|
||||||
bundle assumes that all objects in the basis are already in the
|
bundle assumes that all objects in the basis are already in the
|
||||||
destination repository.
|
destination repository.
|
||||||
@@ -43,7 +43,7 @@ verify <file>::
|
|||||||
bundle format itself as well as checking that the prerequisite
|
bundle format itself as well as checking that the prerequisite
|
||||||
commits exist and are fully linked in the current repository.
|
commits exist and are fully linked in the current repository.
|
||||||
'git-bundle' prints a list of missing commits, if any, and exits
|
'git-bundle' prints a list of missing commits, if any, and exits
|
||||||
with non-zero status.
|
with a non-zero status.
|
||||||
|
|
||||||
list-heads <file>::
|
list-heads <file>::
|
||||||
Lists the references defined in the bundle. If followed by a
|
Lists the references defined in the bundle. If followed by a
|
||||||
@@ -53,14 +53,14 @@ list-heads <file>::
|
|||||||
unbundle <file>::
|
unbundle <file>::
|
||||||
Passes the objects in the bundle to 'git-index-pack'
|
Passes the objects in the bundle to 'git-index-pack'
|
||||||
for storage in the repository, then prints the names of all
|
for storage in the repository, then prints the names of all
|
||||||
defined references. If a reflist is given, only references
|
defined references. If a list of references is given, only
|
||||||
matching those in the given list are printed. This command is
|
references matching those in the list are printed. This command is
|
||||||
really plumbing, intended to be called only by 'git-fetch'.
|
really plumbing, intended to be called only by 'git-fetch'.
|
||||||
|
|
||||||
[git-rev-list-args...]::
|
[git-rev-list-args...]::
|
||||||
A list of arguments, acceptable to 'git-rev-parse' and
|
A list of arguments, acceptable to 'git-rev-parse' and
|
||||||
'git-rev-list', that specify the specific objects and references
|
'git-rev-list', that specifies the specific objects and references
|
||||||
to transport. For example, "master~10..master" causes the
|
to transport. For example, `master\~10..master` causes the
|
||||||
current master reference to be packaged along with all objects
|
current master reference to be packaged along with all objects
|
||||||
added since its 10th ancestor commit. There is no explicit
|
added since its 10th ancestor commit. There is no explicit
|
||||||
limit to the number of references and objects that may be
|
limit to the number of references and objects that may be
|
||||||
@@ -71,24 +71,24 @@ unbundle <file>::
|
|||||||
A list of references used to limit the references reported as
|
A list of references used to limit the references reported as
|
||||||
available. This is principally of use to 'git-fetch', which
|
available. This is principally of use to 'git-fetch', which
|
||||||
expects to receive only those references asked for and not
|
expects to receive only those references asked for and not
|
||||||
necessarily everything in the pack (in this case, 'git-bundle' is
|
necessarily everything in the pack (in this case, 'git-bundle' acts
|
||||||
acting like 'git-fetch-pack').
|
like 'git-fetch-pack').
|
||||||
|
|
||||||
SPECIFYING REFERENCES
|
SPECIFYING REFERENCES
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
'git-bundle' will only package references that are shown by
|
'git-bundle' will only package references that are shown by
|
||||||
'git-show-ref': this includes heads, tags, and remote heads. References
|
'git-show-ref': this includes heads, tags, and remote heads. References
|
||||||
such as master~1 cannot be packaged, but are perfectly suitable for
|
such as `master\~1` cannot be packaged, but are perfectly suitable for
|
||||||
defining the basis. More than one reference may be packaged, and more
|
defining the basis. More than one reference may be packaged, and more
|
||||||
than one basis can be specified. The objects packaged are those not
|
than one basis can be specified. The objects packaged are those not
|
||||||
contained in the union of the given bases. Each basis can be
|
contained in the union of the given bases. Each basis can be
|
||||||
specified explicitly (e.g., ^master~10), or implicitly (e.g.,
|
specified explicitly (e.g. `^master\~10`), or implicitly (e.g.
|
||||||
master~10..master, --since=10.days.ago master).
|
`master\~10..master`, `--since=10.days.ago master`).
|
||||||
|
|
||||||
It is very important that the basis used be held by the destination.
|
It is very important that the basis used be held by the destination.
|
||||||
It is okay to err on the side of conservatism, causing the bundle file
|
It is okay to err on the side of caution, causing the bundle file
|
||||||
to contain objects already in the destination as these are ignored
|
to contain objects already in the destination, as these are ignored
|
||||||
when unpacking at the destination.
|
when unpacking at the destination.
|
||||||
|
|
||||||
EXAMPLE
|
EXAMPLE
|
||||||
@@ -97,13 +97,13 @@ EXAMPLE
|
|||||||
Assume you want to transfer the history from a repository R1 on machine A
|
Assume you want to transfer the history from a repository R1 on machine A
|
||||||
to another repository R2 on machine B.
|
to another repository R2 on machine B.
|
||||||
For whatever reason, direct connection between A and B is not allowed,
|
For whatever reason, direct connection between A and B is not allowed,
|
||||||
but we can move data from A to B via some mechanism (CD, email, etc).
|
but we can move data from A to B via some mechanism (CD, email, etc.).
|
||||||
We want to update R2 with developments made on branch master in R1.
|
We want to update R2 with development made on the branch master in R1.
|
||||||
|
|
||||||
To bootstrap the process, you can first create a bundle that doesn't have
|
To bootstrap the process, you can first create a bundle that does not have
|
||||||
any basis. You can use a tag to remember up to what commit you sent out
|
any basis. You can use a tag to remember up to what commit you last
|
||||||
in order to make it easy to later update the other repository with
|
processed, in order to make it easy to later update the other repository
|
||||||
incremental bundle,
|
with an incremental bundle:
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
machineA$ cd R1
|
machineA$ cd R1
|
||||||
@@ -111,17 +111,17 @@ machineA$ git bundle create file.bundle master
|
|||||||
machineA$ git tag -f lastR2bundle master
|
machineA$ git tag -f lastR2bundle master
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
Then you sneakernet file.bundle to the target machine B. Because you don't
|
Then you transfer file.bundle to the target machine B. If you are creating
|
||||||
have to have any object to extract objects from such a bundle, not only
|
the repository on machine B, then you can clone from the bundle as if it
|
||||||
you can fetch/pull from a bundle, you can clone from it as if it was a
|
were a remote repository instead of creating an empty repository and then
|
||||||
remote repository.
|
pulling or fetching objects from the bundle:
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
machineB$ git clone /home/me/tmp/file.bundle R2
|
machineB$ git clone /home/me/tmp/file.bundle R2
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
This will define a remote called "origin" in the resulting repository that
|
This will define a remote called "origin" in the resulting repository that
|
||||||
lets you fetch and pull from the bundle. $GIT_DIR/config file in R2 may
|
lets you fetch and pull from the bundle. The $GIT_DIR/config file in R2 will
|
||||||
have an entry like this:
|
have an entry like this:
|
||||||
|
|
||||||
------------------------
|
------------------------
|
||||||
@@ -130,12 +130,12 @@ have an entry like this:
|
|||||||
fetch = refs/heads/*:refs/remotes/origin/*
|
fetch = refs/heads/*:refs/remotes/origin/*
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
You can fetch/pull to update the resulting mine.git repository after
|
To update the resulting mine.git repository, you can fetch or pull after
|
||||||
replacing the bundle you store at /home/me/tmp/file.bundle with incremental
|
replacing the bundle stored at /home/me/tmp/file.bundle with incremental
|
||||||
updates from here on.
|
updates.
|
||||||
|
|
||||||
After working more in the original repository, you can create an
|
After working some more in the original repository, you can create an
|
||||||
incremental bundle to update the other:
|
incremental bundle to update the other repository:
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
machineA$ cd R1
|
machineA$ cd R1
|
||||||
@@ -143,8 +143,8 @@ machineA$ git bundle create file.bundle lastR2bundle..master
|
|||||||
machineA$ git tag -f lastR2bundle master
|
machineA$ git tag -f lastR2bundle master
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
and sneakernet it to the other machine to replace /home/me/tmp/file.bundle,
|
You then transfer the bundle to the other machine to replace
|
||||||
and pull from it.
|
/home/me/tmp/file.bundle, and pull from it.
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
machineB$ cd R2
|
machineB$ cd R2
|
||||||
@@ -152,49 +152,49 @@ machineB$ git pull
|
|||||||
----------------
|
----------------
|
||||||
|
|
||||||
If you know up to what commit the intended recipient repository should
|
If you know up to what commit the intended recipient repository should
|
||||||
have the necessary objects for, you can use that knowledge to specify the
|
have the necessary objects, you can use that knowledge to specify the
|
||||||
basis, giving a cut-off point to limit the revisions and objects that go
|
basis, giving a cut-off point to limit the revisions and objects that go
|
||||||
in the resulting bundle. The previous example used lastR2bundle tag
|
in the resulting bundle. The previous example used lastR2bundle tag
|
||||||
for this purpose, but you can use other options you would give to
|
for this purpose, but you can use any other options that you would give to
|
||||||
the linkgit:git-log[1] command. Here are more examples:
|
the linkgit:git-log[1] command. Here are more examples:
|
||||||
|
|
||||||
You can use a tag that is present in both.
|
You can use a tag that is present in both:
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
$ git bundle create mybundle v1.0.0..master
|
$ git bundle create mybundle v1.0.0..master
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
You can use a basis based on time.
|
You can use a basis based on time:
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
$ git bundle create mybundle --since=10.days master
|
$ git bundle create mybundle --since=10.days master
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
Or you can use the number of commits.
|
You can use the number of commits:
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
$ git bundle create mybundle -10 master
|
$ git bundle create mybundle -10 master
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
You can run `git-bundle verify` to see if you can extract from a bundle
|
You can run `git-bundle verify` to see if you can extract from a bundle
|
||||||
that was created with a basis.
|
that was created with a basis:
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
$ git bundle verify mybundle
|
$ git bundle verify mybundle
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
This will list what commits you must have in order to extract from the
|
This will list what commits you must have in order to extract from the
|
||||||
bundle and will error out if you don't have them.
|
bundle and will error out if you do not have them.
|
||||||
|
|
||||||
A bundle from a recipient repository's point of view is just like a
|
A bundle from a recipient repository's point of view is just like a
|
||||||
regular repository it fetches/pulls from. You can for example map
|
regular repository which it fetches or pulls from. You can, for example, map
|
||||||
refs, like this example, when fetching:
|
references when fetching:
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
$ git fetch mybundle master:localRef
|
$ git fetch mybundle master:localRef
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
Or see what refs it offers.
|
You can also see what references it offers.
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
$ git ls-remote mybundle
|
$ git ls-remote mybundle
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ git-cat-file(1)
|
|||||||
|
|
||||||
NAME
|
NAME
|
||||||
----
|
----
|
||||||
git-cat-file - Provide content or type/size information for repository objects
|
git-cat-file - Provide content or type and size information for repository objects
|
||||||
|
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
@@ -14,19 +14,19 @@ SYNOPSIS
|
|||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
In the first form, provides content or type of objects in the repository. The
|
In its first form, the command provides the content or the type of an object in
|
||||||
type is required unless '-t' or '-p' is used to find the object type, or '-s'
|
the repository. The type is required unless '-t' or '-p' is used to find the
|
||||||
is used to find the object size.
|
object type, or '-s' is used to find the object size.
|
||||||
|
|
||||||
In the second form, a list of object (separated by LFs) is provided on stdin,
|
In the second form, a list of objects (separated by linefeeds) is provided on
|
||||||
and the SHA1, type, and size of each object is printed on stdout.
|
stdin, and the SHA1, type, and size of each object is printed on stdout.
|
||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
-------
|
-------
|
||||||
<object>::
|
<object>::
|
||||||
The name of the object to show.
|
The name of the object to show.
|
||||||
For a more complete list of ways to spell object names, see
|
For a more complete list of ways to spell object names, see
|
||||||
"SPECIFYING REVISIONS" section in linkgit:git-rev-parse[1].
|
the "SPECIFYING REVISIONS" section in linkgit:git-rev-parse[1].
|
||||||
|
|
||||||
-t::
|
-t::
|
||||||
Instead of the content, show the object type identified by
|
Instead of the content, show the object type identified by
|
||||||
@@ -56,8 +56,8 @@ OPTIONS
|
|||||||
stdin. May not be combined with any other options or arguments.
|
stdin. May not be combined with any other options or arguments.
|
||||||
|
|
||||||
--batch-check::
|
--batch-check::
|
||||||
Print the SHA1, type, and size of each object provided on stdin. May not be
|
Print the SHA1, type, and size of each object provided on stdin. May not
|
||||||
combined with any other options or arguments.
|
be combined with any other options or arguments.
|
||||||
|
|
||||||
OUTPUT
|
OUTPUT
|
||||||
------
|
------
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ SYNOPSIS
|
|||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
For every pathname, this command will list if each attr is 'unspecified',
|
For every pathname, this command will list if each attribute is 'unspecified',
|
||||||
'set', or 'unset' as a gitattribute on that pathname.
|
'set', or 'unset' as a gitattribute on that pathname.
|
||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
@@ -23,11 +23,11 @@ OPTIONS
|
|||||||
Read file names from stdin instead of from the command-line.
|
Read file names from stdin instead of from the command-line.
|
||||||
|
|
||||||
-z::
|
-z::
|
||||||
Only meaningful with `--stdin`; paths are separated with
|
Only meaningful with `--stdin`; paths are separated with a
|
||||||
NUL character instead of LF.
|
NUL character instead of a linefeed character.
|
||||||
|
|
||||||
\--::
|
\--::
|
||||||
Interpret all preceding arguments as attributes, and all following
|
Interpret all preceding arguments as attributes and all following
|
||||||
arguments as path names. If not supplied, only the first argument will
|
arguments as path names. If not supplied, only the first argument will
|
||||||
be treated as an attribute.
|
be treated as an attribute.
|
||||||
|
|
||||||
@@ -37,12 +37,12 @@ OUTPUT
|
|||||||
The output is of the form:
|
The output is of the form:
|
||||||
<path> COLON SP <attribute> COLON SP <info> LF
|
<path> COLON SP <attribute> COLON SP <info> LF
|
||||||
|
|
||||||
Where <path> is the path of a file being queried, <attribute> is an attribute
|
<path> is the path of a file being queried, <attribute> is an attribute
|
||||||
being queried and <info> can be either:
|
being queried and <info> can be either:
|
||||||
|
|
||||||
'unspecified';; when the attribute is not defined for the path.
|
'unspecified';; when the attribute is not defined for the path.
|
||||||
'unset';; when the attribute is defined to false.
|
'unset';; when the attribute is defined as false.
|
||||||
'set';; when the attribute is defined to true.
|
'set';; when the attribute is defined as true.
|
||||||
<value>;; when a value has been assigned to the attribute.
|
<value>;; when a value has been assigned to the attribute.
|
||||||
|
|
||||||
EXAMPLES
|
EXAMPLES
|
||||||
@@ -69,7 +69,7 @@ org/example/MyClass.java: diff: java
|
|||||||
org/example/MyClass.java: myAttr: set
|
org/example/MyClass.java: myAttr: set
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
* Listing attribute for multiple files:
|
* Listing an attribute for multiple files:
|
||||||
---------------
|
---------------
|
||||||
$ git check-attr myAttr -- org/example/MyClass.java org/example/NoMyAttr.java
|
$ git check-attr myAttr -- org/example/MyClass.java org/example/NoMyAttr.java
|
||||||
org/example/MyClass.java: myAttr: set
|
org/example/MyClass.java: myAttr: set
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ git-check-ref-format(1)
|
|||||||
|
|
||||||
NAME
|
NAME
|
||||||
----
|
----
|
||||||
git-check-ref-format - Make sure ref name is well formed
|
git-check-ref-format - Ensures that a reference name is well formed
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
@@ -11,40 +11,40 @@ SYNOPSIS
|
|||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
Checks if a given 'refname' is acceptable, and exits non-zero if
|
Checks if a given 'refname' is acceptable, and exits with a non-zero
|
||||||
it is not.
|
status if it is not.
|
||||||
|
|
||||||
A reference is used in git to specify branches and tags. A
|
A reference is used in git to specify branches and tags. A
|
||||||
branch head is stored under `$GIT_DIR/refs/heads` directory, and
|
branch head is stored under the `$GIT_DIR/refs/heads` directory, and
|
||||||
a tag is stored under `$GIT_DIR/refs/tags` directory. git
|
a tag is stored under the `$GIT_DIR/refs/tags` directory. git
|
||||||
imposes the following rules on how refs are named:
|
imposes the following rules on how references are named:
|
||||||
|
|
||||||
. It can include slash `/` for hierarchical (directory)
|
. They can include slash `/` for hierarchical (directory)
|
||||||
grouping, but no slash-separated component can begin with a
|
grouping, but no slash-separated component can begin with a
|
||||||
dot `.`;
|
dot `.`.
|
||||||
|
|
||||||
. It cannot have two consecutive dots `..` anywhere;
|
. They cannot have two consecutive dots `..` anywhere.
|
||||||
|
|
||||||
. It cannot have ASCII control character (i.e. bytes whose
|
. They cannot have ASCII control characters (i.e. bytes whose
|
||||||
values are lower than \040, or \177 `DEL`), space, tilde `~`,
|
values are lower than \040, or \177 `DEL`), space, tilde `~`,
|
||||||
caret `{caret}`, colon `:`, question-mark `?`, asterisk `*`,
|
caret `{caret}`, colon `:`, question-mark `?`, asterisk `*`,
|
||||||
or open bracket `[` anywhere;
|
or open bracket `[` anywhere.
|
||||||
|
|
||||||
. It cannot end with a slash `/`.
|
. They cannot end with a slash `/`.
|
||||||
|
|
||||||
These rules makes it easy for shell script based tools to parse
|
These rules make it easy for shell script based tools to parse
|
||||||
refnames, pathname expansion by the shell when a refname is used
|
reference names, pathname expansion by the shell when a reference name is used
|
||||||
unquoted (by mistake), and also avoids ambiguities in certain
|
unquoted (by mistake), and also avoids ambiguities in certain
|
||||||
refname expressions (see linkgit:git-rev-parse[1]). Namely:
|
reference name expressions (see linkgit:git-rev-parse[1]):
|
||||||
|
|
||||||
. double-dot `..` are often used as in `ref1..ref2`, and in some
|
. A double-dot `..` is often used as in `ref1..ref2`, and in some
|
||||||
context this notation means `{caret}ref1 ref2` (i.e. not in
|
contexts this notation means `{caret}ref1 ref2` (i.e. not in
|
||||||
ref1 and in ref2).
|
`ref1` and in `ref2`).
|
||||||
|
|
||||||
. tilde `~` and caret `{caret}` are used to introduce postfix
|
. A tilde `~` and caret `{caret}` are used to introduce the postfix
|
||||||
'nth parent' and 'peel onion' operation.
|
'nth parent' and 'peel onion' operation.
|
||||||
|
|
||||||
. colon `:` is used as in `srcref:dstref` to mean "use srcref\'s
|
. A colon `:` is used as in `srcref:dstref` to mean "use srcref\'s
|
||||||
value and store it in dstref" in fetch and push operations.
|
value and store it in dstref" in fetch and push operations.
|
||||||
It may also be used to select a specific object such as with
|
It may also be used to select a specific object such as with
|
||||||
'git-cat-file': "git cat-file blob v1.3.3:refs.c".
|
'git-cat-file': "git cat-file blob v1.3.3:refs.c".
|
||||||
|
|||||||
@@ -133,9 +133,9 @@ the conflicted merge in the specified paths.
|
|||||||
When this parameter names a non-branch (but still a valid commit object),
|
When this parameter names a non-branch (but still a valid commit object),
|
||||||
your HEAD becomes 'detached'.
|
your HEAD becomes 'detached'.
|
||||||
+
|
+
|
||||||
As a special case, the "`@\{-N\}`" syntax for the N-th last branch
|
As a special case, the `"@\{-N\}"` syntax for the N-th last branch
|
||||||
checks out the branch (instead of detaching). You may also specify
|
checks out the branch (instead of detaching). You may also specify
|
||||||
"`-`" which is synonymous with "`@\{-1\}`".
|
`-` which is synonymous with `"@\{-1\}"`.
|
||||||
|
|
||||||
|
|
||||||
Detached HEAD
|
Detached HEAD
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ then the cloned repository will become corrupt.
|
|||||||
--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> instead.
|
of the upstream repository, use <name>.
|
||||||
|
|
||||||
--upload-pack <upload-pack>::
|
--upload-pack <upload-pack>::
|
||||||
-u <upload-pack>::
|
-u <upload-pack>::
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ SYNOPSIS
|
|||||||
[verse]
|
[verse]
|
||||||
'git config' [<file-option>] [type] [-z|--null] name [value [value_regex]]
|
'git config' [<file-option>] [type] [-z|--null] name [value [value_regex]]
|
||||||
'git config' [<file-option>] [type] --add name value
|
'git config' [<file-option>] [type] --add name value
|
||||||
'git config' [<file-option>] [type] --replace-all name [value [value_regex]]
|
'git config' [<file-option>] [type] --replace-all name value [value_regex]
|
||||||
'git config' [<file-option>] [type] [-z|--null] --get name [value_regex]
|
'git config' [<file-option>] [type] [-z|--null] --get name [value_regex]
|
||||||
'git config' [<file-option>] [type] [-z|--null] --get-all name [value_regex]
|
'git config' [<file-option>] [type] [-z|--null] --get-all name [value_regex]
|
||||||
'git config' [<file-option>] [type] [-z|--null] --get-regexp name_regex [value_regex]
|
'git config' [<file-option>] [type] [-z|--null] --get-regexp name_regex [value_regex]
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ repository, or incrementally import into an existing one.
|
|||||||
Splitting the CVS log into patch sets is done by 'cvsps'.
|
Splitting the CVS log into patch sets is done by 'cvsps'.
|
||||||
At least version 2.1 is required.
|
At least version 2.1 is required.
|
||||||
|
|
||||||
|
*WARNING:* for certain situations the import leads to incorrect results.
|
||||||
|
Please see the section <<issues,ISSUES>> for further reference.
|
||||||
|
|
||||||
You should *never* do any work of your own on the branches that are
|
You should *never* do any work of your own on the branches that are
|
||||||
created by 'git-cvsimport'. By default initial import will create and populate a
|
created by 'git-cvsimport'. By default initial import will create and populate a
|
||||||
"master" branch from the CVS repository's main branch which you're free
|
"master" branch from the CVS repository's main branch which you're free
|
||||||
@@ -62,7 +65,7 @@ OPTIONS
|
|||||||
-r <remote>::
|
-r <remote>::
|
||||||
The git remote to import this CVS repository into.
|
The git remote to import this CVS repository into.
|
||||||
Moves all CVS branches into remotes/<remote>/<branch>
|
Moves all CVS branches into remotes/<remote>/<branch>
|
||||||
akin to the 'git-clone' "--use-separate-remote" option.
|
akin to the way 'git-clone' uses 'origin' by default.
|
||||||
|
|
||||||
-o <branch-for-HEAD>::
|
-o <branch-for-HEAD>::
|
||||||
When no remote is specified (via -r) the 'HEAD' branch
|
When no remote is specified (via -r) the 'HEAD' branch
|
||||||
@@ -164,6 +167,39 @@ If '-v' is specified, the script reports what it is doing.
|
|||||||
Otherwise, success is indicated the Unix way, i.e. by simply exiting with
|
Otherwise, success is indicated the Unix way, i.e. by simply exiting with
|
||||||
a zero exit status.
|
a zero exit status.
|
||||||
|
|
||||||
|
[[issues]]
|
||||||
|
ISSUES
|
||||||
|
------
|
||||||
|
Problems related to timestamps:
|
||||||
|
|
||||||
|
* If timestamps of commits in the cvs repository are not stable enough
|
||||||
|
to be used for ordering commits changes may show up in the wrong
|
||||||
|
order.
|
||||||
|
* If any files were ever "cvs import"ed more than once (e.g., import of
|
||||||
|
more than one vendor release) the HEAD contains the wrong content.
|
||||||
|
* If the timestamp order of different files cross the revision order
|
||||||
|
within the commit matching time window the order of commits may be
|
||||||
|
wrong.
|
||||||
|
|
||||||
|
Problems related to branches:
|
||||||
|
|
||||||
|
* Branches on which no commits have been made are not imported.
|
||||||
|
* All files from the branching point are added to a branch even if
|
||||||
|
never added in cvs.
|
||||||
|
* This applies to files added to the source branch *after* a daughter
|
||||||
|
branch was created: if previously no commit was made on the daughter
|
||||||
|
branch they will erroneously be added to the daughter branch in git.
|
||||||
|
|
||||||
|
Problems related to tags:
|
||||||
|
|
||||||
|
* Multiple tags on the same revision are not imported.
|
||||||
|
|
||||||
|
If you suspect that any of these issues may apply to the repository you
|
||||||
|
want to import consider using these alternative tools which proved to be
|
||||||
|
more stable in practise:
|
||||||
|
|
||||||
|
* cvs2git (part of cvs2svn), `http://cvs2svn.tigris.org`
|
||||||
|
* parsecvs, `http://cgit.freedesktop.org/~keithp/parsecvs`
|
||||||
|
|
||||||
Author
|
Author
|
||||||
------
|
------
|
||||||
|
|||||||
@@ -40,15 +40,11 @@ There are two ways to specify which commits to operate on.
|
|||||||
REVISIONS" section in linkgit:git-rev-parse[1]) means the
|
REVISIONS" section in linkgit:git-rev-parse[1]) means the
|
||||||
commits in the specified range.
|
commits in the specified range.
|
||||||
|
|
||||||
A single commit, when interpreted as a <revision range>
|
The first rule takes precedence in the case of a single <commit>. To
|
||||||
expression, means "everything that leads to that commit", but
|
apply the second rule, i.e., format everything since the beginning of
|
||||||
if you write 'git format-patch <commit>', the previous rule
|
history up until <commit>, use the '\--root' option: "git format-patch
|
||||||
applies to that command line and you do not get "everything
|
\--root <commit>". If you want to format only <commit> itself, you
|
||||||
since the beginning of the time". If you want to format
|
can do this with "git format-patch -1 <commit>".
|
||||||
everything since project inception to one commit, say "git
|
|
||||||
format-patch \--root <commit>" to make it clear that it is the
|
|
||||||
latter case. If you want to format a single commit, you 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
|
||||||
@@ -97,7 +93,6 @@ include::diff-options.txt[]
|
|||||||
--numbered-files::
|
--numbered-files::
|
||||||
Output file names will be a simple number sequence
|
Output file names will be a simple number sequence
|
||||||
without the default first line of the commit appended.
|
without the default first line of the commit appended.
|
||||||
Mutually exclusive with the --stdout option.
|
|
||||||
|
|
||||||
-k::
|
-k::
|
||||||
--keep-subject::
|
--keep-subject::
|
||||||
@@ -162,6 +157,11 @@ if that is not set.
|
|||||||
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 an arbitrary header to the email headers. This is in addition
|
||||||
|
to any configured headers, and may be used multiple times.
|
||||||
|
For example, --add-header="Organization: git-foo"
|
||||||
|
|
||||||
--cover-letter::
|
--cover-letter::
|
||||||
In addition to the patches, generate a cover letter file
|
In addition to the patches, generate a cover letter file
|
||||||
containing the shortlog and the overall diffstat. You can
|
containing the shortlog and the overall diffstat. You can
|
||||||
@@ -183,6 +183,13 @@ not add any suffix.
|
|||||||
applied. By default the contents of changes in those files are
|
applied. By default the contents of changes in those files are
|
||||||
encoded in the patch.
|
encoded in the patch.
|
||||||
|
|
||||||
|
--root::
|
||||||
|
Treat the revision argument as a <revision range>, even if it
|
||||||
|
is just a single commit (that would normally be treated as a
|
||||||
|
<since>). Note that root commits included in the specified
|
||||||
|
range are always formatted as creation patches, independently
|
||||||
|
of this flag.
|
||||||
|
|
||||||
CONFIGURATION
|
CONFIGURATION
|
||||||
-------------
|
-------------
|
||||||
You can specify extra mail header lines to be added to each message
|
You can specify extra mail header lines to be added to each message
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ SYNOPSIS
|
|||||||
[-l | --files-with-matches] [-L | --files-without-match]
|
[-l | --files-with-matches] [-L | --files-without-match]
|
||||||
[-z | --null]
|
[-z | --null]
|
||||||
[-c | --count] [--all-match]
|
[-c | --count] [--all-match]
|
||||||
|
[--color | --no-color]
|
||||||
[-A <post-context>] [-B <pre-context>] [-C <context>]
|
[-A <post-context>] [-B <pre-context>] [-C <context>]
|
||||||
[-f <file>] [-e] <pattern>
|
[-f <file>] [-e] <pattern>
|
||||||
[--and|--or|--not|(|)|-e <pattern>...] [<tree>...]
|
[--and|--or|--not|(|)|-e <pattern>...] [<tree>...]
|
||||||
@@ -105,6 +106,13 @@ OPTIONS
|
|||||||
Instead of showing every matched line, show the number of
|
Instead of showing every matched line, show the number of
|
||||||
lines that match.
|
lines that match.
|
||||||
|
|
||||||
|
--color::
|
||||||
|
Show colored matches.
|
||||||
|
|
||||||
|
--no-color::
|
||||||
|
Turn off match highlighting, even when the configuration file
|
||||||
|
gives the default to color output.
|
||||||
|
|
||||||
-[ABC] <context>::
|
-[ABC] <context>::
|
||||||
Show `context` trailing (`A` -- after), or leading (`B`
|
Show `context` trailing (`A` -- after), or leading (`B`
|
||||||
-- before), or both (`C` -- context) lines, and place a
|
-- before), or both (`C` -- context) lines, and place a
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ include::merge-options.txt[]
|
|||||||
include::merge-strategies.txt[]
|
include::merge-strategies.txt[]
|
||||||
|
|
||||||
|
|
||||||
If you tried a merge which resulted in a complex conflicts and
|
If you tried a merge which resulted in complex conflicts and
|
||||||
would want to start over, you can recover with 'git-reset'.
|
want to start over, you can recover with 'git-reset'.
|
||||||
|
|
||||||
CONFIGURATION
|
CONFIGURATION
|
||||||
-------------
|
-------------
|
||||||
@@ -146,7 +146,7 @@ And here is another line that is cleanly resolved or unmodified.
|
|||||||
------------
|
------------
|
||||||
|
|
||||||
The area where a pair of conflicting changes happened is marked with markers
|
The area where a pair of conflicting changes happened is marked with markers
|
||||||
"`<<<<<<<`", "`=======`", and "`>>>>>>>`". The part before the "`=======`"
|
`<<<<<<<`, `=======`, and `>>>>>>>`. The part before the `=======`
|
||||||
is typically your side, and the part afterwards is typically their side.
|
is typically your side, and the part afterwards is typically their side.
|
||||||
|
|
||||||
The default format does not show what the original said in the conflicting
|
The default format does not show what the original said in the conflicting
|
||||||
@@ -173,8 +173,8 @@ Git makes conflict resolution easy.
|
|||||||
And here is another line that is cleanly resolved or unmodified.
|
And here is another line that is cleanly resolved or unmodified.
|
||||||
------------
|
------------
|
||||||
|
|
||||||
In addition to the "`<<<<<<<`", "`=======`", and "`>>>>>>>`" markers, it uses
|
In addition to the `<<<<<<<`, `=======`, and `>>>>>>>` markers, it uses
|
||||||
another "`|||||||`" marker that is followed by the original text. You can
|
another `|||||||` marker that is followed by the original text. You can
|
||||||
tell that the original just stated a fact, and your side simply gave in to
|
tell that the original just stated a fact, and your side simply gave in to
|
||||||
that statement and gave up, while the other side tried to have a more
|
that statement and gave up, while the other side tried to have a more
|
||||||
positive attitude. You can sometimes come up with a better resolution by
|
positive attitude. You can sometimes come up with a better resolution by
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ IOW, you can use this thing to look for likely duplicate commits.
|
|||||||
|
|
||||||
When dealing with 'git-diff-tree' output, it takes advantage of
|
When dealing with 'git-diff-tree' output, it takes advantage of
|
||||||
the fact that the patch is prefixed with the object name of the
|
the fact that the patch is prefixed with the object name of the
|
||||||
commit, and outputs two 40-byte hexadecimal string. The first
|
commit, and outputs two 40-byte hexadecimal strings. The first
|
||||||
string is the patch ID, and the second string is the commit ID.
|
string is the patch ID, and the second string is the commit ID.
|
||||||
This can be used to make a mapping from patch ID to commit ID.
|
This can be used to make a mapping from patch ID to commit ID.
|
||||||
|
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ every time you push into it, by setting up 'hooks' there. See
|
|||||||
documentation for linkgit:git-receive-pack[1].
|
documentation for linkgit:git-receive-pack[1].
|
||||||
|
|
||||||
|
|
||||||
OPTIONS
|
OPTIONS[[OPTIONS]]
|
||||||
-------
|
------------------
|
||||||
<repository>::
|
<repository>::
|
||||||
The "remote" repository that is destination of a push
|
The "remote" repository that is destination of a push
|
||||||
operation. This parameter can be either a URL
|
operation. This parameter can be either a URL
|
||||||
@@ -187,6 +187,28 @@ reason::
|
|||||||
Examples
|
Examples
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
git push::
|
||||||
|
Works like `git push <remote>`, where <remote> is the
|
||||||
|
current branch's remote (or `origin`, if no remote is
|
||||||
|
configured for the current branch).
|
||||||
|
|
||||||
|
git push origin::
|
||||||
|
Without additional configuration, works like
|
||||||
|
`git push origin :`.
|
||||||
|
+
|
||||||
|
The default behavior of this command when no <refspec> is given can be
|
||||||
|
configured by setting the `push` option of the remote.
|
||||||
|
+
|
||||||
|
For example, to default to pushing only the current branch to `origin`
|
||||||
|
use `git config remote.origin.push HEAD`. Any valid <refspec> (like
|
||||||
|
the ones in the examples below) can be configured as the default for
|
||||||
|
`git push origin`.
|
||||||
|
|
||||||
|
git push origin :::
|
||||||
|
Push "matching" branches to `origin`. See
|
||||||
|
<refspec> in the <<OPTIONS,OPTIONS>> section above for a
|
||||||
|
description of "matching" branches.
|
||||||
|
|
||||||
git push origin master::
|
git push origin master::
|
||||||
Find a ref that matches `master` in the source repository
|
Find a ref that matches `master` in the source repository
|
||||||
(most likely, it would find `refs/heads/master`), and update
|
(most likely, it would find `refs/heads/master`), and update
|
||||||
|
|||||||
@@ -258,11 +258,23 @@ OPTIONS
|
|||||||
context exist they all must match. By default no context is
|
context exist they all must match. By default no context is
|
||||||
ever ignored.
|
ever ignored.
|
||||||
|
|
||||||
|
-f::
|
||||||
|
--force-rebase::
|
||||||
|
Force the rebase even if the current branch is a descendant
|
||||||
|
of the commit you are rebasing onto. Normally the command will
|
||||||
|
exit with the message "Current branch is up to date" in such a
|
||||||
|
situation.
|
||||||
|
|
||||||
--whitespace=<option>::
|
--whitespace=<option>::
|
||||||
This flag is passed to the 'git-apply' program
|
This flag is passed to the 'git-apply' program
|
||||||
(see linkgit:git-apply[1]) that applies the patch.
|
(see linkgit:git-apply[1]) that applies the patch.
|
||||||
Incompatible with the --interactive option.
|
Incompatible with the --interactive option.
|
||||||
|
|
||||||
|
--committer-date-is-author-date::
|
||||||
|
--ignore-date::
|
||||||
|
These flags are passed to 'git-am' to easily change the dates
|
||||||
|
of the rebased commits (see linkgit:git-am[1]).
|
||||||
|
|
||||||
-i::
|
-i::
|
||||||
--interactive::
|
--interactive::
|
||||||
Make a list of the commits which are about to be rebased. Let the
|
Make a list of the commits which are about to be rebased. Let the
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ 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 show' [-n] <name>
|
'git remote show' [-n] <name>
|
||||||
'git remote prune' [-n | --dry-run] <name>
|
'git remote prune' [-n | --dry-run] <name>
|
||||||
'git remote update' [group]
|
'git remote update' [group]
|
||||||
@@ -53,8 +54,7 @@ is created. You can give more than one `-t <branch>` to track
|
|||||||
multiple branches without grabbing all branches.
|
multiple branches without grabbing all branches.
|
||||||
+
|
+
|
||||||
With `-m <master>` option, `$GIT_DIR/remotes/<name>/HEAD` is set
|
With `-m <master>` option, `$GIT_DIR/remotes/<name>/HEAD` is set
|
||||||
up to point at remote's `<master>` branch instead of whatever
|
up to point at remote's `<master>` branch. See also the set-head command.
|
||||||
branch the `HEAD` at the remote repository actually points at.
|
|
||||||
+
|
+
|
||||||
In mirror mode, enabled with `\--mirror`, the refs will not be stored
|
In mirror mode, enabled with `\--mirror`, the refs will not be stored
|
||||||
in the 'refs/remotes/' namespace, but in 'refs/heads/'. This option
|
in the 'refs/remotes/' namespace, but in 'refs/heads/'. This option
|
||||||
@@ -76,6 +76,30 @@ the configuration file format.
|
|||||||
Remove the remote named <name>. All remote tracking branches and
|
Remove the remote named <name>. All remote tracking branches and
|
||||||
configuration settings for the remote are removed.
|
configuration settings for the remote are removed.
|
||||||
|
|
||||||
|
'set-head'::
|
||||||
|
|
||||||
|
Sets or deletes the default branch (`$GIT_DIR/remotes/<name>/HEAD`) for
|
||||||
|
the named remote. Having a default branch for a remote is not required,
|
||||||
|
but allows the name of the remote to be specified in lieu of a specific
|
||||||
|
branch. For example, if the default branch for `origin` is set to
|
||||||
|
`master`, then `origin` may be specified wherever you would normally
|
||||||
|
specify `origin/master`.
|
||||||
|
+
|
||||||
|
With `-d`, `$GIT_DIR/remotes/<name>/HEAD` is deleted.
|
||||||
|
+
|
||||||
|
With `-a`, the remote is queried to determine its `HEAD`, then
|
||||||
|
`$GIT_DIR/remotes/<name>/HEAD` is set to the same branch. e.g., if the remote
|
||||||
|
`HEAD` is pointed at `next`, "`git remote set-head origin -a`" will set
|
||||||
|
`$GIT_DIR/refs/remotes/origin/HEAD` to `refs/remotes/origin/next`. This will
|
||||||
|
only work if `refs/remotes/origin/next` already exists; if not it must be
|
||||||
|
fetched first.
|
||||||
|
+
|
||||||
|
Use `<branch>` to set `$GIT_DIR/remotes/<name>/HEAD` explicitly. e.g., "git
|
||||||
|
remote set-head origin master" will set `$GIT_DIR/refs/remotes/origin/HEAD` to
|
||||||
|
`refs/remotes/origin/master`. This will only work if
|
||||||
|
`refs/remotes/origin/master` already exists; if not it must be fetched first.
|
||||||
|
+
|
||||||
|
|
||||||
'show'::
|
'show'::
|
||||||
|
|
||||||
Gives some information about the remote <name>.
|
Gives some information about the remote <name>.
|
||||||
|
|||||||
@@ -299,18 +299,18 @@ previous section means the set of commits reachable from that
|
|||||||
commit, following the commit ancestry chain.
|
commit, following the commit ancestry chain.
|
||||||
|
|
||||||
To exclude commits reachable from a commit, a prefix `{caret}`
|
To exclude commits reachable from a commit, a prefix `{caret}`
|
||||||
notation is used. E.g. "`{caret}r1 r2`" means commits reachable
|
notation is used. E.g. `{caret}r1 r2` means commits reachable
|
||||||
from `r2` but exclude the ones reachable from `r1`.
|
from `r2` but exclude the ones reachable from `r1`.
|
||||||
|
|
||||||
This set operation appears so often that there is a shorthand
|
This set operation appears so often that there is a shorthand
|
||||||
for it. When you have two commits `r1` and `r2` (named according
|
for it. When you have two commits `r1` and `r2` (named according
|
||||||
to the syntax explained in SPECIFYING REVISIONS above), you can ask
|
to the syntax explained in SPECIFYING REVISIONS above), you can ask
|
||||||
for commits that are reachable from r2 excluding those that are reachable
|
for commits that are reachable from r2 excluding those that are reachable
|
||||||
from r1 by "`{caret}r1 r2`" and it can be written as "`r1..r2`".
|
from r1 by `{caret}r1 r2` and it can be written as `r1..r2`.
|
||||||
|
|
||||||
A similar notation "`r1\...r2`" is called symmetric difference
|
A similar notation `r1\...r2` is called symmetric difference
|
||||||
of `r1` and `r2` and is defined as
|
of `r1` and `r2` and is defined as
|
||||||
"`r1 r2 --not $(git merge-base --all r1 r2)`".
|
`r1 r2 --not $(git merge-base --all r1 r2)`.
|
||||||
It is the set of commits that are reachable from either one of
|
It is the set of commits that are reachable from either one of
|
||||||
`r1` or `r2` but not from both.
|
`r1` or `r2` but not from both.
|
||||||
|
|
||||||
|
|||||||
@@ -60,14 +60,13 @@ The --cc option must be repeated for each user you want on the cc list.
|
|||||||
Use $GIT_EDITOR, core.editor, $VISUAL, or $EDITOR to edit an
|
Use $GIT_EDITOR, core.editor, $VISUAL, or $EDITOR to edit an
|
||||||
introductory message for the patch series.
|
introductory message for the patch series.
|
||||||
+
|
+
|
||||||
When '--compose' is used, git send-email gets less interactive will use the
|
When '--compose' is used, git send-email will use the From, Subject, and
|
||||||
values of the headers you set there. If the body of the email (what you type
|
In-Reply-To headers specified in the message. If the body of the message
|
||||||
after the headers and a blank line) only contains blank (or GIT: prefixed)
|
(what you type after the headers and a blank line) only contains blank
|
||||||
lines, the summary won't be sent, but git-send-email will still use the
|
(or GIT: prefixed) lines the summary won't be sent, but From, Subject,
|
||||||
Headers values if you don't removed them.
|
and In-Reply-To headers will be used unless they are removed.
|
||||||
+
|
+
|
||||||
If it wasn't able to see a header in the summary it will ask you about it
|
Missing From or In-Reply-To headers will be prompted for.
|
||||||
interactively after quitting your editor.
|
|
||||||
|
|
||||||
--from::
|
--from::
|
||||||
Specify the sender of the emails. This will default to
|
Specify the sender of the emails. This will default to
|
||||||
|
|||||||
@@ -385,7 +385,8 @@ config key: svn.authorsfile
|
|||||||
|
|
||||||
-q::
|
-q::
|
||||||
--quiet::
|
--quiet::
|
||||||
Make 'git-svn' less verbose.
|
Make 'git-svn' less verbose. Specify a second time to make it
|
||||||
|
even less verbose.
|
||||||
|
|
||||||
--repack[=<n>]::
|
--repack[=<n>]::
|
||||||
--repack-flags=<flags>::
|
--repack-flags=<flags>::
|
||||||
@@ -672,9 +673,9 @@ listed below are allowed:
|
|||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
[svn-remote "project-a"]
|
[svn-remote "project-a"]
|
||||||
url = http://server.org/svn
|
url = http://server.org/svn
|
||||||
|
fetch = trunk/project-a:refs/remotes/project-a/trunk
|
||||||
branches = branches/*/project-a:refs/remotes/project-a/branches/*
|
branches = branches/*/project-a:refs/remotes/project-a/branches/*
|
||||||
tags = tags/*/project-a:refs/remotes/project-a/tags/*
|
tags = tags/*/project-a:refs/remotes/project-a/tags/*
|
||||||
trunk = trunk/project-a:refs/remotes/project-a/trunk
|
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
Keep in mind that the '*' (asterisk) wildcard of the local ref
|
Keep in mind that the '*' (asterisk) wildcard of the local ref
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ OPTIONS
|
|||||||
are printed when using -l.
|
are printed when using -l.
|
||||||
The default is not to print any annotation lines.
|
The default is not to print any annotation lines.
|
||||||
If no number is given to `-n`, only the first line is printed.
|
If no number is given to `-n`, only the first line is printed.
|
||||||
|
If the tag is not annotated, the commit message is displayed instead.
|
||||||
|
|
||||||
-l <pattern>::
|
-l <pattern>::
|
||||||
List tags with names that match the given pattern (or all if no pattern is given).
|
List tags with names that match the given pattern (or all if no pattern is given).
|
||||||
|
|||||||
@@ -46,20 +46,20 @@ Here are the rules regarding the "flags" that you should follow when you are
|
|||||||
scripting git:
|
scripting git:
|
||||||
|
|
||||||
* it's preferred to use the non dashed form of git commands, which means that
|
* it's preferred to use the non dashed form of git commands, which means that
|
||||||
you should prefer `"git foo"` to `"git-foo"`.
|
you should prefer `git foo` to `git-foo`.
|
||||||
|
|
||||||
* splitting short options to separate words (prefer `"git foo -a -b"`
|
* splitting short options to separate words (prefer `git foo -a -b`
|
||||||
to `"git foo -ab"`, the latter may not even work).
|
to `git foo -ab`, the latter may not even work).
|
||||||
|
|
||||||
* when a command line option takes an argument, use the 'sticked' form. In
|
* when a command line option takes an argument, use the 'sticked' form. In
|
||||||
other words, write `"git foo -oArg"` instead of `"git foo -o Arg"` for short
|
other words, write `git foo -oArg` instead of `git foo -o Arg` for short
|
||||||
options, and `"git foo --long-opt=Arg"` instead of `"git foo --long-opt Arg"`
|
options, and `git foo --long-opt=Arg` instead of `git foo --long-opt Arg`
|
||||||
for long options. An option that takes optional option-argument must be
|
for long options. An option that takes optional option-argument must be
|
||||||
written in the 'sticked' form.
|
written in the 'sticked' form.
|
||||||
|
|
||||||
* when you give a revision parameter to a command, make sure the parameter is
|
* when you give a revision parameter to a command, make sure the parameter is
|
||||||
not ambiguous with a name of a file in the work tree. E.g. do not write
|
not ambiguous with a name of a file in the work tree. E.g. do not write
|
||||||
`"git log -1 HEAD"` but write `"git log -1 HEAD --"`; the former will not work
|
`git log -1 HEAD` but write `git log -1 HEAD --`; the former will not work
|
||||||
if you happen to have a file called `HEAD` in the work tree.
|
if you happen to have a file called `HEAD` in the work tree.
|
||||||
|
|
||||||
|
|
||||||
@@ -99,17 +99,17 @@ usage: git-describe [options] <committish>*
|
|||||||
|
|
||||||
Negating options
|
Negating options
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
Options with long option names can be negated by prefixing `"--no-"`. For
|
Options with long option names can be negated by prefixing `--no-`. For
|
||||||
example, `"git branch"` has the option `"--track"` which is 'on' by default. You
|
example, `git branch` has the option `--track` which is 'on' by default. You
|
||||||
can use `"--no-track"` to override that behaviour. The same goes for `"--color"`
|
can use `--no-track` to override that behaviour. The same goes for `--color`
|
||||||
and `"--no-color"`.
|
and `--no-color`.
|
||||||
|
|
||||||
|
|
||||||
Aggregating short options
|
Aggregating short options
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
Commands that support the enhanced option parser allow you to aggregate short
|
Commands that support the enhanced option parser allow you to aggregate short
|
||||||
options. This means that you can for example use `"git rm -rf"` or
|
options. This means that you can for example use `git rm -rf` or
|
||||||
`"git clean -fdx"`.
|
`git clean -fdx`.
|
||||||
|
|
||||||
|
|
||||||
Separating argument from the option
|
Separating argument from the option
|
||||||
|
|||||||
@@ -151,6 +151,10 @@ indicating whether the checkout was a branch checkout (changing branches,
|
|||||||
flag=1) or a file checkout (retrieving a file from the index, flag=0).
|
flag=1) or a file checkout (retrieving a file from the index, flag=0).
|
||||||
This hook cannot affect the outcome of 'git-checkout'.
|
This hook cannot affect the outcome of 'git-checkout'.
|
||||||
|
|
||||||
|
It is also run after 'git-clone', unless the --no-checkout (-n) option is
|
||||||
|
used. The first parameter given to the hook is the null-ref, the second the
|
||||||
|
ref of the new HEAD and the flag is always 1.
|
||||||
|
|
||||||
This hook can be used to perform repository validity checks, auto-display
|
This hook can be used to perform repository validity checks, auto-display
|
||||||
differences from the previous HEAD if different, or set working dir metadata
|
differences from the previous HEAD if different, or set working dir metadata
|
||||||
properties.
|
properties.
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ This commit is referred to as a "merge commit", or sometimes just a
|
|||||||
'origin' is used for that purpose. New upstream updates
|
'origin' is used for that purpose. New upstream updates
|
||||||
will be fetched into remote <<def_tracking_branch,tracking branches>> named
|
will be fetched into remote <<def_tracking_branch,tracking branches>> named
|
||||||
origin/name-of-upstream-branch, which you can see using
|
origin/name-of-upstream-branch, which you can see using
|
||||||
"`git branch -r`".
|
`git branch -r`.
|
||||||
|
|
||||||
[[def_pack]]pack::
|
[[def_pack]]pack::
|
||||||
A set of objects which have been compressed into one file (to save space
|
A set of objects which have been compressed into one file (to save space
|
||||||
|
|||||||
@@ -5,22 +5,21 @@ canonical real names and email addresses.
|
|||||||
|
|
||||||
In the simple form, each line in the file consists of the canonical
|
In the simple form, each line in the file consists of the canonical
|
||||||
real name of an author, whitespace, and an email address used in the
|
real name of an author, whitespace, and an email address used in the
|
||||||
commit (enclosed by '<' and '>') to map to the name. Thus, looks like
|
commit (enclosed by '<' and '>') to map to the name. For example:
|
||||||
this
|
|
||||||
--
|
--
|
||||||
Proper Name <commit@email.xx>
|
Proper Name <commit@email.xx>
|
||||||
--
|
--
|
||||||
|
|
||||||
The more complex forms are
|
The more complex forms are:
|
||||||
--
|
--
|
||||||
<proper@email.xx> <commit@email.xx>
|
<proper@email.xx> <commit@email.xx>
|
||||||
--
|
--
|
||||||
which allows mailmap to replace only the email part of a commit, and
|
which allows mailmap to replace only the email part of a commit, and:
|
||||||
--
|
--
|
||||||
Proper Name <proper@email.xx> <commit@email.xx>
|
Proper Name <proper@email.xx> <commit@email.xx>
|
||||||
--
|
--
|
||||||
which allows mailmap to replace both the name and the email of a
|
which allows mailmap to replace both the name and the email of a
|
||||||
commit matching the specified commit email address, and
|
commit matching the specified commit email address, and:
|
||||||
--
|
--
|
||||||
Proper Name <proper@email.xx> Commit Name <commit@email.xx>
|
Proper Name <proper@email.xx> Commit Name <commit@email.xx>
|
||||||
--
|
--
|
||||||
@@ -47,8 +46,8 @@ Jane Doe <jane@desktop.(none)>
|
|||||||
Joe R. Developer <joe@example.com>
|
Joe R. Developer <joe@example.com>
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Note how we don't need an entry for <jane@laptop.(none)>, because the
|
Note how there is no need for an entry for <jane@laptop.(none)>, because the
|
||||||
real name of that author is correct already.
|
real name of that author is already correct.
|
||||||
|
|
||||||
Example 2: Your repository contains commits from the following
|
Example 2: Your repository contains commits from the following
|
||||||
authors:
|
authors:
|
||||||
@@ -62,7 +61,7 @@ claus <me@company.xx>
|
|||||||
CTO <cto@coompany.xx>
|
CTO <cto@coompany.xx>
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Then, you might want a `.mailmap` file looking like:
|
Then you might want a `.mailmap` file that looks like:
|
||||||
------------
|
------------
|
||||||
<cto@company.xx> <cto@coompany.xx>
|
<cto@company.xx> <cto@coompany.xx>
|
||||||
Some Dude <some@dude.xx> nick1 <bugs@company.xx>
|
Some Dude <some@dude.xx> nick1 <bugs@company.xx>
|
||||||
@@ -72,4 +71,4 @@ Santa Claus <santa.claus@northpole.xx> <me@company.xx>
|
|||||||
------------
|
------------
|
||||||
|
|
||||||
Use hash '#' for comments that are either on their own line, or after
|
Use hash '#' for comments that are either on their own line, or after
|
||||||
the email address.
|
the email address.
|
||||||
|
|||||||
@@ -1,21 +1,14 @@
|
|||||||
<!-- Based on callouts.xsl. Fixes man page callouts for DocBook 1.72 XSL -->
|
<!-- manpage-1.72.xsl:
|
||||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
special settings for manpages rendered from asciidoc+docbook
|
||||||
|
handles peculiarities in docbook-xsl 1.72.0 -->
|
||||||
|
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||||
|
version="1.0">
|
||||||
|
|
||||||
<xsl:param name="man.output.quietly" select="1"/>
|
<xsl:import href="manpage-base.xsl"/>
|
||||||
<xsl:param name="refentry.meta.get.quietly" select="1"/>
|
|
||||||
|
|
||||||
<xsl:template match="co">
|
<!-- these are the special values for the roff control characters
|
||||||
<xsl:value-of select="concat('▓fB(',substring-after(@id,'-'),')▓fR')"/>
|
needed for docbook-xsl 1.72.0 -->
|
||||||
</xsl:template>
|
<xsl:param name="git.docbook.backslash">▓</xsl:param>
|
||||||
<xsl:template match="calloutlist">
|
<xsl:param name="git.docbook.dot" >⌂</xsl:param>
|
||||||
<xsl:text>⌂sp </xsl:text>
|
|
||||||
<xsl:apply-templates/>
|
|
||||||
<xsl:text> </xsl:text>
|
|
||||||
</xsl:template>
|
|
||||||
<xsl:template match="callout">
|
|
||||||
<xsl:value-of select="concat('▓fB',substring-after(@arearefs,'-'),'. ▓fR')"/>
|
|
||||||
<xsl:apply-templates/>
|
|
||||||
<xsl:text>⌂br </xsl:text>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
</xsl:stylesheet>
|
</xsl:stylesheet>
|
||||||
|
|||||||
35
Documentation/manpage-base.xsl
Normal file
35
Documentation/manpage-base.xsl
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<!-- manpage-base.xsl:
|
||||||
|
special formatting for manpages rendered from asciidoc+docbook -->
|
||||||
|
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||||
|
version="1.0">
|
||||||
|
|
||||||
|
<!-- these params silence some output from xmlto -->
|
||||||
|
<xsl:param name="man.output.quietly" select="1"/>
|
||||||
|
<xsl:param name="refentry.meta.get.quietly" select="1"/>
|
||||||
|
|
||||||
|
<!-- convert asciidoc callouts to man page format;
|
||||||
|
git.docbook.backslash and git.docbook.dot params
|
||||||
|
must be supplied by another XSL file or other means -->
|
||||||
|
<xsl:template match="co">
|
||||||
|
<xsl:value-of select="concat(
|
||||||
|
$git.docbook.backslash,'fB(',
|
||||||
|
substring-after(@id,'-'),')',
|
||||||
|
$git.docbook.backslash,'fR')"/>
|
||||||
|
</xsl:template>
|
||||||
|
<xsl:template match="calloutlist">
|
||||||
|
<xsl:value-of select="$git.docbook.dot"/>
|
||||||
|
<xsl:text>sp </xsl:text>
|
||||||
|
<xsl:apply-templates/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
<xsl:template match="callout">
|
||||||
|
<xsl:value-of select="concat(
|
||||||
|
$git.docbook.backslash,'fB',
|
||||||
|
substring-after(@arearefs,'-'),
|
||||||
|
'. ',$git.docbook.backslash,'fR')"/>
|
||||||
|
<xsl:apply-templates/>
|
||||||
|
<xsl:value-of select="$git.docbook.dot"/>
|
||||||
|
<xsl:text>br </xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
</xsl:stylesheet>
|
||||||
17
Documentation/manpage-bold-literal.xsl
Normal file
17
Documentation/manpage-bold-literal.xsl
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<!-- manpage-bold-literal.xsl:
|
||||||
|
special formatting for manpages rendered from asciidoc+docbook -->
|
||||||
|
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||||
|
version="1.0">
|
||||||
|
|
||||||
|
<!-- render literal text as bold (instead of plain or monospace);
|
||||||
|
this makes literal text easier to distinguish in manpages
|
||||||
|
viewed on a tty -->
|
||||||
|
<xsl:template match="literal">
|
||||||
|
<xsl:value-of select="$git.docbook.backslash"/>
|
||||||
|
<xsl:text>fB</xsl:text>
|
||||||
|
<xsl:apply-templates/>
|
||||||
|
<xsl:value-of select="$git.docbook.backslash"/>
|
||||||
|
<xsl:text>fR</xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
</xsl:stylesheet>
|
||||||
13
Documentation/manpage-normal.xsl
Normal file
13
Documentation/manpage-normal.xsl
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!-- manpage-normal.xsl:
|
||||||
|
special settings for manpages rendered from asciidoc+docbook
|
||||||
|
handles anything we want to keep away from docbook-xsl 1.72.0 -->
|
||||||
|
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||||
|
version="1.0">
|
||||||
|
|
||||||
|
<xsl:import href="manpage-base.xsl"/>
|
||||||
|
|
||||||
|
<!-- these are the normal values for the roff control characters -->
|
||||||
|
<xsl:param name="git.docbook.backslash">\</xsl:param>
|
||||||
|
<xsl:param name="git.docbook.dot" >.</xsl:param>
|
||||||
|
|
||||||
|
</xsl:stylesheet>
|
||||||
21
Documentation/manpage-suppress-sp.xsl
Normal file
21
Documentation/manpage-suppress-sp.xsl
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<!-- manpage-suppress-sp.xsl:
|
||||||
|
special settings for manpages rendered from asciidoc+docbook
|
||||||
|
handles erroneous, inline .sp in manpage output of some
|
||||||
|
versions of docbook-xsl -->
|
||||||
|
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||||
|
version="1.0">
|
||||||
|
|
||||||
|
<!-- attempt to work around spurious .sp at the tail of the line
|
||||||
|
that some versions of docbook stylesheets seem to add -->
|
||||||
|
<xsl:template match="simpara">
|
||||||
|
<xsl:variable name="content">
|
||||||
|
<xsl:apply-templates/>
|
||||||
|
</xsl:variable>
|
||||||
|
<xsl:value-of select="normalize-space($content)"/>
|
||||||
|
<xsl:if test="not(ancestor::authorblurb) and
|
||||||
|
not(ancestor::personblurb)">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
</xsl:stylesheet>
|
||||||
@@ -3,15 +3,15 @@ MERGE STRATEGIES
|
|||||||
|
|
||||||
resolve::
|
resolve::
|
||||||
This can only resolve two heads (i.e. the current branch
|
This can only resolve two heads (i.e. the current branch
|
||||||
and another branch you pulled from) using 3-way merge
|
and another branch you pulled from) using a 3-way merge
|
||||||
algorithm. It tries to carefully detect criss-cross
|
algorithm. It tries to carefully detect criss-cross
|
||||||
merge ambiguities and is considered generally safe and
|
merge ambiguities and is considered generally safe and
|
||||||
fast.
|
fast.
|
||||||
|
|
||||||
recursive::
|
recursive::
|
||||||
This can only resolve two heads using 3-way merge
|
This can only resolve two heads using a 3-way merge
|
||||||
algorithm. When there are more than one common
|
algorithm. When there is more than one common
|
||||||
ancestors that can be used for 3-way merge, it creates a
|
ancestor that can be used for 3-way merge, it creates a
|
||||||
merged tree of the common ancestors and uses that as
|
merged tree of the common ancestors and uses that as
|
||||||
the reference tree for the 3-way merge. This has been
|
the reference tree for the 3-way merge. This has been
|
||||||
reported to result in fewer merge conflicts without
|
reported to result in fewer merge conflicts without
|
||||||
@@ -22,11 +22,11 @@ recursive::
|
|||||||
pulling or merging one branch.
|
pulling or merging one branch.
|
||||||
|
|
||||||
octopus::
|
octopus::
|
||||||
This resolves more than two-head case, but refuses to do
|
This resolves cases with more than two heads, but refuses to do
|
||||||
complex merge that needs manual resolution. It is
|
a complex merge that needs manual resolution. It is
|
||||||
primarily meant to be used for bundling topic branch
|
primarily meant to be used for bundling topic branch
|
||||||
heads together. This is the default merge strategy when
|
heads together. This is the default merge strategy when
|
||||||
pulling or merging more than one branches.
|
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 result of the
|
||||||
|
|||||||
@@ -148,22 +148,22 @@ outputting that information, if desired.
|
|||||||
------------
|
------------
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
M
|
*
|
||||||
|\
|
|\
|
||||||
* |
|
* |
|
||||||
| | *
|
| | *
|
||||||
| \ \
|
| \ \
|
||||||
| \ \
|
| \ \
|
||||||
M-. \ \
|
*-. \ \
|
||||||
|\ \ \ \
|
|\ \ \ \
|
||||||
| | * | |
|
| | * | |
|
||||||
| | | | | *
|
| | | | | *
|
||||||
| | | | | *
|
| | | | | *
|
||||||
| | | | | M
|
| | | | | *
|
||||||
| | | | | |\
|
| | | | | |\
|
||||||
| | | | | | *
|
| | | | | | *
|
||||||
| * | | | | |
|
| * | | | | |
|
||||||
| | | | | M \
|
| | | | | * \
|
||||||
| | | | | |\ |
|
| | | | | |\ |
|
||||||
| | | | * | | |
|
| | | | * | | |
|
||||||
| | | | * | | |
|
| | | | * | | |
|
||||||
|
|||||||
@@ -1136,10 +1136,10 @@ Ignoring files
|
|||||||
A project will often generate files that you do 'not' want to track with git.
|
A project will often generate files that you do 'not' want to track with git.
|
||||||
This typically includes files generated by a build process or temporary
|
This typically includes files generated by a build process or temporary
|
||||||
backup files made by your editor. Of course, 'not' tracking files with git
|
backup files made by your editor. Of course, 'not' tracking files with git
|
||||||
is just a matter of 'not' calling "`git-add`" on them. But it quickly becomes
|
is just a matter of 'not' calling `git-add` on them. But it quickly becomes
|
||||||
annoying to have these untracked files lying around; e.g. they make
|
annoying to have these untracked files lying around; e.g. they make
|
||||||
"`git add .`" practically useless, and they keep showing up in the output of
|
`git add .` practically useless, and they keep showing up in the output of
|
||||||
"`git status`".
|
`git status`.
|
||||||
|
|
||||||
You can tell git to ignore certain files by creating a file called .gitignore
|
You can tell git to ignore certain files by creating a file called .gitignore
|
||||||
in the top level of your working directory, with contents such as:
|
in the top level of your working directory, with contents such as:
|
||||||
|
|||||||
37
Makefile
37
Makefile
@@ -126,6 +126,12 @@ all::
|
|||||||
# randomly break unless your underlying filesystem supports those sub-second
|
# randomly break unless your underlying filesystem supports those sub-second
|
||||||
# times (my ext3 doesn't).
|
# times (my ext3 doesn't).
|
||||||
#
|
#
|
||||||
|
# Define USE_ST_TIMESPEC if your "struct stat" uses "st_ctimespec" instead of
|
||||||
|
# "st_ctim"
|
||||||
|
#
|
||||||
|
# Define NO_NSEC if your "struct stat" does not have "st_ctim.tv_nsec"
|
||||||
|
# available. This automatically turns USE_NSEC off.
|
||||||
|
#
|
||||||
# Define USE_STDEV below if you want git to care about the underlying device
|
# Define USE_STDEV below if you want git to care about the underlying device
|
||||||
# change being considered an inode change from the update-index perspective.
|
# change being considered an inode change from the update-index perspective.
|
||||||
#
|
#
|
||||||
@@ -258,6 +264,18 @@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
|
|||||||
BASIC_CFLAGS =
|
BASIC_CFLAGS =
|
||||||
BASIC_LDFLAGS =
|
BASIC_LDFLAGS =
|
||||||
|
|
||||||
|
# Guard against environment variables
|
||||||
|
BUILTIN_OBJS =
|
||||||
|
BUILT_INS =
|
||||||
|
COMPAT_CFLAGS =
|
||||||
|
COMPAT_OBJS =
|
||||||
|
LIB_H =
|
||||||
|
LIB_OBJS =
|
||||||
|
PROGRAMS =
|
||||||
|
SCRIPT_PERL =
|
||||||
|
SCRIPT_SH =
|
||||||
|
TEST_PROGRAMS =
|
||||||
|
|
||||||
SCRIPT_SH += git-am.sh
|
SCRIPT_SH += git-am.sh
|
||||||
SCRIPT_SH += git-bisect.sh
|
SCRIPT_SH += git-bisect.sh
|
||||||
SCRIPT_SH += git-filter-branch.sh
|
SCRIPT_SH += git-filter-branch.sh
|
||||||
@@ -658,6 +676,7 @@ ifeq ($(uname_S),Darwin)
|
|||||||
endif
|
endif
|
||||||
NO_MEMMEM = YesPlease
|
NO_MEMMEM = YesPlease
|
||||||
THREADED_DELTA_SEARCH = YesPlease
|
THREADED_DELTA_SEARCH = YesPlease
|
||||||
|
USE_ST_TIMESPEC = YesPlease
|
||||||
endif
|
endif
|
||||||
ifeq ($(uname_S),SunOS)
|
ifeq ($(uname_S),SunOS)
|
||||||
NEEDS_SOCKET = YesPlease
|
NEEDS_SOCKET = YesPlease
|
||||||
@@ -707,6 +726,7 @@ ifeq ($(uname_S),FreeBSD)
|
|||||||
BASIC_CFLAGS += -I/usr/local/include
|
BASIC_CFLAGS += -I/usr/local/include
|
||||||
BASIC_LDFLAGS += -L/usr/local/lib
|
BASIC_LDFLAGS += -L/usr/local/lib
|
||||||
DIR_HAS_BSD_GROUP_SEMANTICS = YesPlease
|
DIR_HAS_BSD_GROUP_SEMANTICS = YesPlease
|
||||||
|
USE_ST_TIMESPEC = YesPlease
|
||||||
THREADED_DELTA_SEARCH = YesPlease
|
THREADED_DELTA_SEARCH = YesPlease
|
||||||
ifeq ($(shell expr "$(uname_R)" : '4\.'),2)
|
ifeq ($(shell expr "$(uname_R)" : '4\.'),2)
|
||||||
PTHREAD_LIBS = -pthread
|
PTHREAD_LIBS = -pthread
|
||||||
@@ -735,6 +755,7 @@ ifeq ($(uname_S),AIX)
|
|||||||
NO_MEMMEM = YesPlease
|
NO_MEMMEM = YesPlease
|
||||||
NO_MKDTEMP = YesPlease
|
NO_MKDTEMP = YesPlease
|
||||||
NO_STRLCPY = YesPlease
|
NO_STRLCPY = YesPlease
|
||||||
|
NO_NSEC = YesPlease
|
||||||
FREAD_READS_DIRECTORIES = UnfortunatelyYes
|
FREAD_READS_DIRECTORIES = UnfortunatelyYes
|
||||||
INTERNAL_QSORT = UnfortunatelyYes
|
INTERNAL_QSORT = UnfortunatelyYes
|
||||||
NEEDS_LIBICONV=YesPlease
|
NEEDS_LIBICONV=YesPlease
|
||||||
@@ -804,6 +825,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
|
|||||||
RUNTIME_PREFIX = YesPlease
|
RUNTIME_PREFIX = YesPlease
|
||||||
NO_POSIX_ONLY_PROGRAMS = YesPlease
|
NO_POSIX_ONLY_PROGRAMS = YesPlease
|
||||||
NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
|
NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
|
||||||
|
NO_NSEC = YesPlease
|
||||||
USE_WIN32_MMAP = YesPlease
|
USE_WIN32_MMAP = YesPlease
|
||||||
COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/regex -Icompat/fnmatch
|
COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/regex -Icompat/fnmatch
|
||||||
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
|
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
|
||||||
@@ -926,6 +948,15 @@ endif
|
|||||||
ifdef NO_ST_BLOCKS_IN_STRUCT_STAT
|
ifdef NO_ST_BLOCKS_IN_STRUCT_STAT
|
||||||
BASIC_CFLAGS += -DNO_ST_BLOCKS_IN_STRUCT_STAT
|
BASIC_CFLAGS += -DNO_ST_BLOCKS_IN_STRUCT_STAT
|
||||||
endif
|
endif
|
||||||
|
ifdef USE_NSEC
|
||||||
|
BASIC_CFLAGS += -DUSE_NSEC
|
||||||
|
endif
|
||||||
|
ifdef USE_ST_TIMESPEC
|
||||||
|
BASIC_CFLAGS += -DUSE_ST_TIMESPEC
|
||||||
|
endif
|
||||||
|
ifdef NO_NSEC
|
||||||
|
BASIC_CFLAGS += -DNO_NSEC
|
||||||
|
endif
|
||||||
ifdef NO_C99_FORMAT
|
ifdef NO_C99_FORMAT
|
||||||
BASIC_CFLAGS += -DNO_C99_FORMAT
|
BASIC_CFLAGS += -DNO_C99_FORMAT
|
||||||
endif
|
endif
|
||||||
@@ -973,6 +1004,11 @@ endif
|
|||||||
ifdef NO_MMAP
|
ifdef NO_MMAP
|
||||||
COMPAT_CFLAGS += -DNO_MMAP
|
COMPAT_CFLAGS += -DNO_MMAP
|
||||||
COMPAT_OBJS += compat/mmap.o
|
COMPAT_OBJS += compat/mmap.o
|
||||||
|
else
|
||||||
|
ifdef USE_WIN32_MMAP
|
||||||
|
COMPAT_CFLAGS += -DUSE_WIN32_MMAP
|
||||||
|
COMPAT_OBJS += compat/win32mmap.o
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
ifdef USE_WIN32_MMAP
|
ifdef USE_WIN32_MMAP
|
||||||
COMPAT_CFLAGS += -DUSE_WIN32_MMAP
|
COMPAT_CFLAGS += -DUSE_WIN32_MMAP
|
||||||
@@ -1373,6 +1409,7 @@ GIT-CFLAGS: .FORCE-GIT-CFLAGS
|
|||||||
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 TAR=\''$(subst ','\'',$(subst ','\'',$(TAR)))'\' >>$@
|
@echo TAR=\''$(subst ','\'',$(subst ','\'',$(TAR)))'\' >>$@
|
||||||
|
@echo NO_CURL=\''$(subst ','\'',$(subst ','\'',$(NO_CURL)))'\' >>$@
|
||||||
|
|
||||||
### Detect Tck/Tk interpreter path changes
|
### Detect Tck/Tk interpreter path changes
|
||||||
ifndef NO_TCLTK
|
ifndef NO_TCLTK
|
||||||
|
|||||||
73
attr.c
73
attr.c
@@ -1,3 +1,4 @@
|
|||||||
|
#define NO_THE_INDEX_COMPATIBILITY_MACROS
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "attr.h"
|
#include "attr.h"
|
||||||
|
|
||||||
@@ -318,6 +319,9 @@ static struct attr_stack *read_attr_from_array(const char **list)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum git_attr_direction direction;
|
||||||
|
static struct index_state *use_index;
|
||||||
|
|
||||||
static struct attr_stack *read_attr_from_file(const char *path, int macro_ok)
|
static struct attr_stack *read_attr_from_file(const char *path, int macro_ok)
|
||||||
{
|
{
|
||||||
FILE *fp = fopen(path, "r");
|
FILE *fp = fopen(path, "r");
|
||||||
@@ -340,9 +344,10 @@ static void *read_index_data(const char *path)
|
|||||||
unsigned long sz;
|
unsigned long sz;
|
||||||
enum object_type type;
|
enum object_type type;
|
||||||
void *data;
|
void *data;
|
||||||
|
struct index_state *istate = use_index ? use_index : &the_index;
|
||||||
|
|
||||||
len = strlen(path);
|
len = strlen(path);
|
||||||
pos = cache_name_pos(path, len);
|
pos = index_name_pos(istate, path, len);
|
||||||
if (pos < 0) {
|
if (pos < 0) {
|
||||||
/*
|
/*
|
||||||
* We might be in the middle of a merge, in which
|
* We might be in the middle of a merge, in which
|
||||||
@@ -350,15 +355,15 @@ static void *read_index_data(const char *path)
|
|||||||
*/
|
*/
|
||||||
int i;
|
int i;
|
||||||
for (i = -pos - 1;
|
for (i = -pos - 1;
|
||||||
(pos < 0 && i < active_nr &&
|
(pos < 0 && i < istate->cache_nr &&
|
||||||
!strcmp(active_cache[i]->name, path));
|
!strcmp(istate->cache[i]->name, path));
|
||||||
i++)
|
i++)
|
||||||
if (ce_stage(active_cache[i]) == 2)
|
if (ce_stage(istate->cache[i]) == 2)
|
||||||
pos = i;
|
pos = i;
|
||||||
}
|
}
|
||||||
if (pos < 0)
|
if (pos < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
data = read_sha1_file(active_cache[pos]->sha1, &type, &sz);
|
data = read_sha1_file(istate->cache[pos]->sha1, &type, &sz);
|
||||||
if (!data || type != OBJ_BLOB) {
|
if (!data || type != OBJ_BLOB) {
|
||||||
free(data);
|
free(data);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -366,27 +371,17 @@ static void *read_index_data(const char *path)
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct attr_stack *read_attr(const char *path, int macro_ok)
|
static struct attr_stack *read_attr_from_index(const char *path, int macro_ok)
|
||||||
{
|
{
|
||||||
struct attr_stack *res;
|
struct attr_stack *res;
|
||||||
char *buf, *sp;
|
char *buf, *sp;
|
||||||
int lineno = 0;
|
int lineno = 0;
|
||||||
|
|
||||||
res = read_attr_from_file(path, macro_ok);
|
|
||||||
if (res)
|
|
||||||
return res;
|
|
||||||
|
|
||||||
res = xcalloc(1, sizeof(*res));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* There is no checked out .gitattributes file there, but
|
|
||||||
* we might have it in the index. We allow operation in a
|
|
||||||
* sparsely checked out work tree, so read from it.
|
|
||||||
*/
|
|
||||||
buf = read_index_data(path);
|
buf = read_index_data(path);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return res;
|
return NULL;
|
||||||
|
|
||||||
|
res = xcalloc(1, sizeof(*res));
|
||||||
for (sp = buf; *sp; ) {
|
for (sp = buf; *sp; ) {
|
||||||
char *ep;
|
char *ep;
|
||||||
int more;
|
int more;
|
||||||
@@ -401,6 +396,30 @@ static struct attr_stack *read_attr(const char *path, int macro_ok)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct attr_stack *read_attr(const char *path, int macro_ok)
|
||||||
|
{
|
||||||
|
struct attr_stack *res;
|
||||||
|
|
||||||
|
if (direction == GIT_ATTR_CHECKOUT) {
|
||||||
|
res = read_attr_from_index(path, macro_ok);
|
||||||
|
if (!res)
|
||||||
|
res = read_attr_from_file(path, macro_ok);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
res = read_attr_from_file(path, macro_ok);
|
||||||
|
if (!res)
|
||||||
|
/*
|
||||||
|
* There is no checked out .gitattributes file there, but
|
||||||
|
* we might have it in the index. We allow operation in a
|
||||||
|
* sparsely checked out work tree, so read from it.
|
||||||
|
*/
|
||||||
|
res = read_attr_from_index(path, macro_ok);
|
||||||
|
}
|
||||||
|
if (!res)
|
||||||
|
res = xcalloc(1, sizeof(*res));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
#if DEBUG_ATTR
|
#if DEBUG_ATTR
|
||||||
static void debug_info(const char *what, struct attr_stack *elem)
|
static void debug_info(const char *what, struct attr_stack *elem)
|
||||||
{
|
{
|
||||||
@@ -428,6 +447,15 @@ static void debug_set(const char *what, const char *match, struct git_attr *attr
|
|||||||
#define debug_set(a,b,c,d) do { ; } while (0)
|
#define debug_set(a,b,c,d) do { ; } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void drop_attr_stack(void)
|
||||||
|
{
|
||||||
|
while (attr_stack) {
|
||||||
|
struct attr_stack *elem = attr_stack;
|
||||||
|
attr_stack = elem->prev;
|
||||||
|
free_attr_elem(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void bootstrap_attr_stack(void)
|
static void bootstrap_attr_stack(void)
|
||||||
{
|
{
|
||||||
if (!attr_stack) {
|
if (!attr_stack) {
|
||||||
@@ -642,3 +670,12 @@ int git_checkattr(const char *path, int num, struct git_attr_check *check)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void git_attr_set_direction(enum git_attr_direction new, struct index_state *istate)
|
||||||
|
{
|
||||||
|
enum git_attr_direction old = direction;
|
||||||
|
direction = new;
|
||||||
|
if (new != old)
|
||||||
|
drop_attr_stack();
|
||||||
|
use_index = istate;
|
||||||
|
}
|
||||||
|
|||||||
6
attr.h
6
attr.h
@@ -31,4 +31,10 @@ struct git_attr_check {
|
|||||||
|
|
||||||
int git_checkattr(const char *path, int, struct git_attr_check *);
|
int git_checkattr(const char *path, int, struct git_attr_check *);
|
||||||
|
|
||||||
|
enum git_attr_direction {
|
||||||
|
GIT_ATTR_CHECKIN,
|
||||||
|
GIT_ATTR_CHECKOUT
|
||||||
|
};
|
||||||
|
void git_attr_set_direction(enum git_attr_direction, struct index_state *);
|
||||||
|
|
||||||
#endif /* ATTR_H */
|
#endif /* ATTR_H */
|
||||||
|
|||||||
60
branch.c
60
branch.c
@@ -32,21 +32,59 @@ static int find_tracked_branch(struct remote *remote, void *priv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int should_setup_rebase(const struct tracking *tracking)
|
static int should_setup_rebase(const char *origin)
|
||||||
{
|
{
|
||||||
switch (autorebase) {
|
switch (autorebase) {
|
||||||
case AUTOREBASE_NEVER:
|
case AUTOREBASE_NEVER:
|
||||||
return 0;
|
return 0;
|
||||||
case AUTOREBASE_LOCAL:
|
case AUTOREBASE_LOCAL:
|
||||||
return tracking->remote == NULL;
|
return origin == NULL;
|
||||||
case AUTOREBASE_REMOTE:
|
case AUTOREBASE_REMOTE:
|
||||||
return tracking->remote != NULL;
|
return origin != NULL;
|
||||||
case AUTOREBASE_ALWAYS:
|
case AUTOREBASE_ALWAYS:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void install_branch_config(int flag, const char *local, const char *origin, const char *remote)
|
||||||
|
{
|
||||||
|
struct strbuf key = STRBUF_INIT;
|
||||||
|
int rebasing = should_setup_rebase(origin);
|
||||||
|
|
||||||
|
strbuf_addf(&key, "branch.%s.remote", local);
|
||||||
|
git_config_set(key.buf, origin ? origin : ".");
|
||||||
|
|
||||||
|
strbuf_reset(&key);
|
||||||
|
strbuf_addf(&key, "branch.%s.merge", local);
|
||||||
|
git_config_set(key.buf, remote);
|
||||||
|
|
||||||
|
if (rebasing) {
|
||||||
|
strbuf_reset(&key);
|
||||||
|
strbuf_addf(&key, "branch.%s.rebase", local);
|
||||||
|
git_config_set(key.buf, "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag & BRANCH_CONFIG_VERBOSE) {
|
||||||
|
strbuf_reset(&key);
|
||||||
|
|
||||||
|
strbuf_addstr(&key, origin ? "remote" : "local");
|
||||||
|
|
||||||
|
/* Are we tracking a proper "branch"? */
|
||||||
|
if (!prefixcmp(remote, "refs/heads/")) {
|
||||||
|
strbuf_addf(&key, " branch %s", remote + 11);
|
||||||
|
if (origin)
|
||||||
|
strbuf_addf(&key, " from %s", origin);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strbuf_addf(&key, " ref %s", remote);
|
||||||
|
printf("Branch %s set up to track %s%s.\n",
|
||||||
|
local, key.buf,
|
||||||
|
rebasing ? " by rebasing" : "");
|
||||||
|
}
|
||||||
|
strbuf_release(&key);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is called when new_ref is branched off of orig_ref, and tries
|
* This is called when new_ref is branched off of orig_ref, and tries
|
||||||
* to infer the settings for branch.<new_ref>.{remote,merge} from the
|
* to infer the settings for branch.<new_ref>.{remote,merge} from the
|
||||||
@@ -55,7 +93,6 @@ static int should_setup_rebase(const struct tracking *tracking)
|
|||||||
static int setup_tracking(const char *new_ref, const char *orig_ref,
|
static int setup_tracking(const char *new_ref, const char *orig_ref,
|
||||||
enum branch_track track)
|
enum branch_track track)
|
||||||
{
|
{
|
||||||
char key[1024];
|
|
||||||
struct tracking tracking;
|
struct tracking tracking;
|
||||||
|
|
||||||
if (strlen(new_ref) > 1024 - 7 - 7 - 1)
|
if (strlen(new_ref) > 1024 - 7 - 7 - 1)
|
||||||
@@ -80,19 +117,10 @@ static int setup_tracking(const char *new_ref, const char *orig_ref,
|
|||||||
return error("Not tracking: ambiguous information for ref %s",
|
return error("Not tracking: ambiguous information for ref %s",
|
||||||
orig_ref);
|
orig_ref);
|
||||||
|
|
||||||
sprintf(key, "branch.%s.remote", new_ref);
|
install_branch_config(BRANCH_CONFIG_VERBOSE, new_ref, tracking.remote,
|
||||||
git_config_set(key, tracking.remote ? tracking.remote : ".");
|
tracking.src ? tracking.src : orig_ref);
|
||||||
sprintf(key, "branch.%s.merge", new_ref);
|
|
||||||
git_config_set(key, tracking.src ? tracking.src : orig_ref);
|
|
||||||
printf("Branch %s set up to track %s branch %s.\n", new_ref,
|
|
||||||
tracking.remote ? "remote" : "local", orig_ref);
|
|
||||||
if (should_setup_rebase(&tracking)) {
|
|
||||||
sprintf(key, "branch.%s.rebase", new_ref);
|
|
||||||
git_config_set(key, "true");
|
|
||||||
printf("This branch will rebase on pull.\n");
|
|
||||||
}
|
|
||||||
free(tracking.src);
|
|
||||||
|
|
||||||
|
free(tracking.src);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
7
branch.h
7
branch.h
@@ -21,4 +21,11 @@ void create_branch(const char *head, const char *name, const char *start_name,
|
|||||||
*/
|
*/
|
||||||
void remove_branch_state(void);
|
void remove_branch_state(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configure local branch "local" to merge remote branch "remote"
|
||||||
|
* taken from origin "origin".
|
||||||
|
*/
|
||||||
|
#define BRANCH_CONFIG_VERBOSE 01
|
||||||
|
extern void install_branch_config(int flag, const char *local, const char *origin, const char *remote);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ static void fill_directory(struct dir_struct *dir, const char **pathspec,
|
|||||||
/* Set up the default git porcelain excludes */
|
/* Set up the default git porcelain excludes */
|
||||||
memset(dir, 0, sizeof(*dir));
|
memset(dir, 0, sizeof(*dir));
|
||||||
if (!ignored_too) {
|
if (!ignored_too) {
|
||||||
dir->collect_ignored = 1;
|
dir->flags |= DIR_COLLECT_IGNORED;
|
||||||
setup_standard_excludes(dir);
|
setup_standard_excludes(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ static const char **validate_pathspec(int argc, const char **argv, const char *p
|
|||||||
if (pathspec) {
|
if (pathspec) {
|
||||||
const char **p;
|
const char **p;
|
||||||
for (p = pathspec; *p; p++) {
|
for (p = pathspec; *p; p++) {
|
||||||
if (has_symlink_leading_path(strlen(*p), *p)) {
|
if (has_symlink_leading_path(*p, strlen(*p))) {
|
||||||
int len = prefix ? strlen(prefix) : 0;
|
int len = prefix ? strlen(prefix) : 0;
|
||||||
die("'%s' is beyond a symbolic link", *p + len);
|
die("'%s' is beyond a symbolic link", *p + len);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2360,7 +2360,7 @@ static int check_to_create_blob(const char *new_name, int ok_if_exists)
|
|||||||
* In such a case, path "new_name" does not exist as
|
* In such a case, path "new_name" does not exist as
|
||||||
* far as git is concerned.
|
* far as git is concerned.
|
||||||
*/
|
*/
|
||||||
if (has_symlink_leading_path(strlen(new_name), new_name))
|
if (has_symlink_leading_path(new_name, strlen(new_name)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return error("%s: already exists in working directory", new_name);
|
return error("%s: already exists in working directory", new_name);
|
||||||
@@ -2451,7 +2451,7 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
|
|||||||
if ((st_mode ^ patch->old_mode) & S_IFMT)
|
if ((st_mode ^ patch->old_mode) & S_IFMT)
|
||||||
return error("%s: wrong type", old_name);
|
return error("%s: wrong type", old_name);
|
||||||
if (st_mode != patch->old_mode)
|
if (st_mode != patch->old_mode)
|
||||||
fprintf(stderr, "warning: %s has type %o, expected %o\n",
|
warning("%s has type %o, expected %o",
|
||||||
old_name, st_mode, patch->old_mode);
|
old_name, st_mode, patch->old_mode);
|
||||||
if (!patch->new_mode && !patch->is_delete)
|
if (!patch->new_mode && !patch->is_delete)
|
||||||
patch->new_mode = st_mode;
|
patch->new_mode = st_mode;
|
||||||
@@ -2932,8 +2932,7 @@ static int write_out_one_reject(struct patch *patch)
|
|||||||
cnt = strlen(patch->new_name);
|
cnt = strlen(patch->new_name);
|
||||||
if (ARRAY_SIZE(namebuf) <= cnt + 5) {
|
if (ARRAY_SIZE(namebuf) <= cnt + 5) {
|
||||||
cnt = ARRAY_SIZE(namebuf) - 5;
|
cnt = ARRAY_SIZE(namebuf) - 5;
|
||||||
fprintf(stderr,
|
warning("truncating .rej filename to %.*s.rej",
|
||||||
"warning: truncating .rej filename to %.*s.rej",
|
|
||||||
cnt - 1, patch->new_name);
|
cnt - 1, patch->new_name);
|
||||||
}
|
}
|
||||||
memcpy(namebuf, patch->new_name, cnt);
|
memcpy(namebuf, patch->new_name, cnt);
|
||||||
@@ -3212,7 +3211,7 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
|
|||||||
|
|
||||||
struct option builtin_apply_options[] = {
|
struct option builtin_apply_options[] = {
|
||||||
{ OPTION_CALLBACK, 0, "exclude", NULL, "path",
|
{ OPTION_CALLBACK, 0, "exclude", NULL, "path",
|
||||||
"don´t apply changes matching the given path",
|
"don't apply changes matching the given path",
|
||||||
0, option_parse_exclude },
|
0, option_parse_exclude },
|
||||||
{ OPTION_CALLBACK, 0, "include", NULL, "path",
|
{ OPTION_CALLBACK, 0, "include", NULL, "path",
|
||||||
"apply changes matching the given path",
|
"apply changes matching the given path",
|
||||||
@@ -3224,10 +3223,10 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
|
|||||||
"ignore additions made by the patch"),
|
"ignore additions made by the patch"),
|
||||||
OPT_BOOLEAN(0, "stat", &diffstat,
|
OPT_BOOLEAN(0, "stat", &diffstat,
|
||||||
"instead of applying the patch, output diffstat for the input"),
|
"instead of applying the patch, output diffstat for the input"),
|
||||||
OPT_BOOLEAN(0, "allow-binary-replacement", &binary,
|
{ OPTION_BOOLEAN, 0, "allow-binary-replacement", &binary,
|
||||||
"now no-op"),
|
NULL, "old option, now no-op", PARSE_OPT_HIDDEN },
|
||||||
OPT_BOOLEAN(0, "binary", &binary,
|
{ OPTION_BOOLEAN, 0, "binary", &binary,
|
||||||
"now no-op"),
|
NULL, "old option, now no-op", PARSE_OPT_HIDDEN },
|
||||||
OPT_BOOLEAN(0, "numstat", &numstat,
|
OPT_BOOLEAN(0, "numstat", &numstat,
|
||||||
"shows number of added and deleted lines in decimal notation"),
|
"shows number of added and deleted lines in decimal notation"),
|
||||||
OPT_BOOLEAN(0, "summary", &summary,
|
OPT_BOOLEAN(0, "summary", &summary,
|
||||||
@@ -3315,8 +3314,8 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
|
|||||||
squelch_whitespace_errors < whitespace_error) {
|
squelch_whitespace_errors < whitespace_error) {
|
||||||
int squelched =
|
int squelched =
|
||||||
whitespace_error - squelch_whitespace_errors;
|
whitespace_error - squelch_whitespace_errors;
|
||||||
fprintf(stderr, "warning: squelched %d "
|
warning("squelched %d "
|
||||||
"whitespace error%s\n",
|
"whitespace error%s",
|
||||||
squelched,
|
squelched,
|
||||||
squelched == 1 ? "" : "s");
|
squelched == 1 ? "" : "s");
|
||||||
}
|
}
|
||||||
@@ -3326,12 +3325,12 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
|
|||||||
whitespace_error == 1 ? "" : "s",
|
whitespace_error == 1 ? "" : "s",
|
||||||
whitespace_error == 1 ? "s" : "");
|
whitespace_error == 1 ? "s" : "");
|
||||||
if (applied_after_fixing_ws && apply)
|
if (applied_after_fixing_ws && apply)
|
||||||
fprintf(stderr, "warning: %d line%s applied after"
|
warning("%d line%s applied after"
|
||||||
" fixing whitespace errors.\n",
|
" fixing whitespace errors.",
|
||||||
applied_after_fixing_ws,
|
applied_after_fixing_ws,
|
||||||
applied_after_fixing_ws == 1 ? "" : "s");
|
applied_after_fixing_ws == 1 ? "" : "s");
|
||||||
else if (whitespace_error)
|
else if (whitespace_error)
|
||||||
fprintf(stderr, "warning: %d line%s add%s whitespace errors.\n",
|
warning("%d line%s add%s whitespace errors.",
|
||||||
whitespace_error,
|
whitespace_error,
|
||||||
whitespace_error == 1 ? "" : "s",
|
whitespace_error == 1 ? "" : "s",
|
||||||
whitespace_error == 1 ? "s" : "");
|
whitespace_error == 1 ? "s" : "");
|
||||||
|
|||||||
@@ -2250,6 +2250,10 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
|
|||||||
parse_done:
|
parse_done:
|
||||||
argc = parse_options_end(&ctx);
|
argc = parse_options_end(&ctx);
|
||||||
|
|
||||||
|
if (revs_file && read_ancestry(revs_file))
|
||||||
|
die("reading graft file %s failed: %s",
|
||||||
|
revs_file, strerror(errno));
|
||||||
|
|
||||||
if (cmd_is_annotate) {
|
if (cmd_is_annotate) {
|
||||||
output_option |= OUTPUT_ANNOTATE_COMPAT;
|
output_option |= OUTPUT_ANNOTATE_COMPAT;
|
||||||
blame_date_mode = DATE_ISO8601;
|
blame_date_mode = DATE_ISO8601;
|
||||||
@@ -2418,10 +2422,6 @@ parse_done:
|
|||||||
sb.ent = ent;
|
sb.ent = ent;
|
||||||
sb.path = path;
|
sb.path = path;
|
||||||
|
|
||||||
if (revs_file && read_ancestry(revs_file))
|
|
||||||
die("reading graft file %s failed: %s",
|
|
||||||
revs_file, strerror(errno));
|
|
||||||
|
|
||||||
read_mailmap(&mailmap, NULL);
|
read_mailmap(&mailmap, NULL);
|
||||||
|
|
||||||
if (!incremental)
|
if (!incremental)
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds)
|
|||||||
ret = 1;
|
ret = 1;
|
||||||
} else {
|
} else {
|
||||||
struct strbuf buf = STRBUF_INIT;
|
struct strbuf buf = STRBUF_INIT;
|
||||||
printf("Deleted %sbranch %s (%s).\n", remote,
|
printf("Deleted %sbranch %s (was %s).\n", remote,
|
||||||
bname.buf,
|
bname.buf,
|
||||||
find_unique_abbrev(sha1, DEFAULT_ABBREV));
|
find_unique_abbrev(sha1, DEFAULT_ABBREV));
|
||||||
strbuf_addf(&buf, "branch.%s", bname.buf);
|
strbuf_addf(&buf, "branch.%s", bname.buf);
|
||||||
|
|||||||
@@ -407,7 +407,7 @@ static int merge_working_tree(struct checkout_opts *opts,
|
|||||||
topts.verbose_update = !opts->quiet;
|
topts.verbose_update = !opts->quiet;
|
||||||
topts.fn = twoway_merge;
|
topts.fn = twoway_merge;
|
||||||
topts.dir = xcalloc(1, sizeof(*topts.dir));
|
topts.dir = xcalloc(1, sizeof(*topts.dir));
|
||||||
topts.dir->show_ignored = 1;
|
topts.dir->flags |= DIR_SHOW_IGNORED;
|
||||||
topts.dir->exclude_per_dir = ".gitignore";
|
topts.dir->exclude_per_dir = ".gitignore";
|
||||||
tree = parse_tree_indirect(old->commit->object.sha1);
|
tree = parse_tree_indirect(old->commit->object.sha1);
|
||||||
init_tree_desc(&trees[0], tree->buffer, tree->size);
|
init_tree_desc(&trees[0], tree->buffer, tree->size);
|
||||||
@@ -558,8 +558,8 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
|
|||||||
|
|
||||||
if (!old.commit && !opts->force) {
|
if (!old.commit && !opts->force) {
|
||||||
if (!opts->quiet) {
|
if (!opts->quiet) {
|
||||||
fprintf(stderr, "warning: You appear to be on a branch yet to be born.\n");
|
warning("You appear to be on a branch yet to be born.");
|
||||||
fprintf(stderr, "warning: Forcing checkout of %s.\n", new->name);
|
warning("Forcing checkout of %s.", new->name);
|
||||||
}
|
}
|
||||||
opts->force = 1;
|
opts->force = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
|
|||||||
|
|
||||||
memset(&dir, 0, sizeof(dir));
|
memset(&dir, 0, sizeof(dir));
|
||||||
if (ignored_only)
|
if (ignored_only)
|
||||||
dir.show_ignored = 1;
|
dir.flags |= DIR_SHOW_IGNORED;
|
||||||
|
|
||||||
if (ignored && ignored_only)
|
if (ignored && ignored_only)
|
||||||
die("-x and -X cannot be used together");
|
die("-x and -X cannot be used together");
|
||||||
@@ -69,7 +69,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
|
|||||||
die("clean.requireForce%s set and -n or -f not given; "
|
die("clean.requireForce%s set and -n or -f not given; "
|
||||||
"refusing to clean", config_set ? "" : " not");
|
"refusing to clean", config_set ? "" : " not");
|
||||||
|
|
||||||
dir.show_other_directories = 1;
|
dir.flags |= DIR_SHOW_OTHER_DIRECTORIES;
|
||||||
|
|
||||||
if (!ignored)
|
if (!ignored)
|
||||||
setup_standard_excludes(&dir);
|
setup_standard_excludes(&dir);
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
#include "dir.h"
|
#include "dir.h"
|
||||||
#include "pack-refs.h"
|
#include "pack-refs.h"
|
||||||
#include "sigchain.h"
|
#include "sigchain.h"
|
||||||
|
#include "branch.h"
|
||||||
|
#include "remote.h"
|
||||||
#include "run-command.h"
|
#include "run-command.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -268,7 +270,7 @@ static const struct ref *clone_local(const char *src_repo,
|
|||||||
|
|
||||||
static const char *junk_work_tree;
|
static const char *junk_work_tree;
|
||||||
static const char *junk_git_dir;
|
static const char *junk_git_dir;
|
||||||
pid_t junk_pid;
|
static pid_t junk_pid;
|
||||||
|
|
||||||
static void remove_junk(void)
|
static void remove_junk(void)
|
||||||
{
|
{
|
||||||
@@ -294,43 +296,6 @@ static void remove_junk_on_signal(int signo)
|
|||||||
raise(signo);
|
raise(signo);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct ref *locate_head(const struct ref *refs,
|
|
||||||
const struct ref *mapped_refs,
|
|
||||||
const struct ref **remote_head_p)
|
|
||||||
{
|
|
||||||
const struct ref *remote_head = NULL;
|
|
||||||
const struct ref *remote_master = NULL;
|
|
||||||
const struct ref *r;
|
|
||||||
for (r = refs; r; r = r->next)
|
|
||||||
if (!strcmp(r->name, "HEAD"))
|
|
||||||
remote_head = r;
|
|
||||||
|
|
||||||
for (r = mapped_refs; r; r = r->next)
|
|
||||||
if (!strcmp(r->name, "refs/heads/master"))
|
|
||||||
remote_master = r;
|
|
||||||
|
|
||||||
if (remote_head_p)
|
|
||||||
*remote_head_p = remote_head;
|
|
||||||
|
|
||||||
/* If there's no HEAD value at all, never mind. */
|
|
||||||
if (!remote_head)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* If refs/heads/master could be right, it is. */
|
|
||||||
if (remote_master && !hashcmp(remote_master->old_sha1,
|
|
||||||
remote_head->old_sha1))
|
|
||||||
return remote_master;
|
|
||||||
|
|
||||||
/* Look for another ref that points there */
|
|
||||||
for (r = mapped_refs; r; r = r->next)
|
|
||||||
if (r != remote_head &&
|
|
||||||
!hashcmp(r->old_sha1, remote_head->old_sha1))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
/* Nothing is the same */
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ref *write_remote_refs(const struct ref *refs,
|
static struct ref *write_remote_refs(const struct ref *refs,
|
||||||
struct refspec *refspec, const char *reflog)
|
struct refspec *refspec, const char *reflog)
|
||||||
{
|
{
|
||||||
@@ -351,19 +316,6 @@ static struct ref *write_remote_refs(const struct ref *refs,
|
|||||||
return local_refs;
|
return local_refs;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void install_branch_config(const char *local,
|
|
||||||
const char *origin,
|
|
||||||
const char *remote)
|
|
||||||
{
|
|
||||||
struct strbuf key = STRBUF_INIT;
|
|
||||||
strbuf_addf(&key, "branch.%s.remote", local);
|
|
||||||
git_config_set(key.buf, origin);
|
|
||||||
strbuf_reset(&key);
|
|
||||||
strbuf_addf(&key, "branch.%s.merge", local);
|
|
||||||
git_config_set(key.buf, remote);
|
|
||||||
strbuf_release(&key);
|
|
||||||
}
|
|
||||||
|
|
||||||
int cmd_clone(int argc, const char **argv, const char *prefix)
|
int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int is_bundle = 0;
|
int is_bundle = 0;
|
||||||
@@ -378,7 +330,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||||||
char *src_ref_prefix = "refs/heads/";
|
char *src_ref_prefix = "refs/heads/";
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
struct refspec refspec;
|
struct refspec *refspec;
|
||||||
|
const char *fetch_pattern;
|
||||||
|
|
||||||
junk_pid = getpid();
|
junk_pid = getpid();
|
||||||
|
|
||||||
@@ -453,7 +406,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||||||
atexit(remove_junk);
|
atexit(remove_junk);
|
||||||
sigchain_push_common(remove_junk_on_signal);
|
sigchain_push_common(remove_junk_on_signal);
|
||||||
|
|
||||||
setenv(CONFIG_ENVIRONMENT, xstrdup(mkpath("%s/config", git_dir)), 1);
|
setenv(CONFIG_ENVIRONMENT, mkpath("%s/config", git_dir), 1);
|
||||||
|
|
||||||
if (safe_create_leading_directories_const(git_dir) < 0)
|
if (safe_create_leading_directories_const(git_dir) < 0)
|
||||||
die("could not create leading directories of '%s'", git_dir);
|
die("could not create leading directories of '%s'", git_dir);
|
||||||
@@ -483,8 +436,14 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||||||
strbuf_addf(&branch_top, "refs/remotes/%s/", option_origin);
|
strbuf_addf(&branch_top, "refs/remotes/%s/", option_origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top.buf);
|
||||||
|
|
||||||
if (option_mirror || !option_bare) {
|
if (option_mirror || !option_bare) {
|
||||||
/* Configure the remote */
|
/* Configure the remote */
|
||||||
|
strbuf_addf(&key, "remote.%s.fetch", option_origin);
|
||||||
|
git_config_set_multivar(key.buf, value.buf, "^$", 0);
|
||||||
|
strbuf_reset(&key);
|
||||||
|
|
||||||
if (option_mirror) {
|
if (option_mirror) {
|
||||||
strbuf_addf(&key, "remote.%s.mirror", option_origin);
|
strbuf_addf(&key, "remote.%s.mirror", option_origin);
|
||||||
git_config_set(key.buf, "true");
|
git_config_set(key.buf, "true");
|
||||||
@@ -493,19 +452,13 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||||||
|
|
||||||
strbuf_addf(&key, "remote.%s.url", option_origin);
|
strbuf_addf(&key, "remote.%s.url", option_origin);
|
||||||
git_config_set(key.buf, repo);
|
git_config_set(key.buf, repo);
|
||||||
strbuf_reset(&key);
|
|
||||||
|
|
||||||
strbuf_addf(&key, "remote.%s.fetch", option_origin);
|
|
||||||
strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top.buf);
|
|
||||||
git_config_set_multivar(key.buf, value.buf, "^$", 0);
|
|
||||||
strbuf_reset(&key);
|
strbuf_reset(&key);
|
||||||
strbuf_reset(&value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
refspec.force = 0;
|
fetch_pattern = value.buf;
|
||||||
refspec.pattern = 1;
|
refspec = parse_fetch_refspec(1, &fetch_pattern);
|
||||||
refspec.src = src_ref_prefix;
|
|
||||||
refspec.dst = branch_top.buf;
|
strbuf_reset(&value);
|
||||||
|
|
||||||
if (path && !is_bundle)
|
if (path && !is_bundle)
|
||||||
refs = clone_local(path, git_dir);
|
refs = clone_local(path, git_dir);
|
||||||
@@ -539,9 +492,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||||||
if (refs) {
|
if (refs) {
|
||||||
clear_extra_refs();
|
clear_extra_refs();
|
||||||
|
|
||||||
mapped_refs = write_remote_refs(refs, &refspec, reflog_msg.buf);
|
mapped_refs = write_remote_refs(refs, refspec, reflog_msg.buf);
|
||||||
|
|
||||||
head_points_at = locate_head(refs, mapped_refs, &remote_head);
|
remote_head = find_ref_by_name(refs, "HEAD");
|
||||||
|
head_points_at = guess_remote_head(remote_head, mapped_refs, 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
warning("You appear to have cloned an empty repository.");
|
warning("You appear to have cloned an empty repository.");
|
||||||
@@ -549,7 +503,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||||||
remote_head = NULL;
|
remote_head = NULL;
|
||||||
option_no_checkout = 1;
|
option_no_checkout = 1;
|
||||||
if (!option_bare)
|
if (!option_bare)
|
||||||
install_branch_config("master", option_origin,
|
install_branch_config(0, "master", option_origin,
|
||||||
"refs/heads/master");
|
"refs/heads/master");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -579,7 +533,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||||||
head_points_at->peer_ref->name,
|
head_points_at->peer_ref->name,
|
||||||
reflog_msg.buf);
|
reflog_msg.buf);
|
||||||
|
|
||||||
install_branch_config(head, option_origin,
|
install_branch_config(0, head, option_origin,
|
||||||
head_points_at->name);
|
head_points_at->name);
|
||||||
}
|
}
|
||||||
} else if (remote_head) {
|
} else if (remote_head) {
|
||||||
|
|||||||
427
builtin-config.c
427
builtin-config.c
@@ -1,9 +1,12 @@
|
|||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
|
#include "parse-options.h"
|
||||||
|
|
||||||
static const char git_config_set_usage[] =
|
static const char *const builtin_config_usage[] = {
|
||||||
"git config [ --global | --system | [ -f | --file ] config-file ] [ --bool | --int | --bool-or-int ] [ -z | --null ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list | --get-color var [default] | --get-colorbool name [stdout-is-tty] | --edit | -e ]";
|
"git config [options]",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
static char *key;
|
static char *key;
|
||||||
static regex_t *key_regexp;
|
static regex_t *key_regexp;
|
||||||
@@ -16,7 +19,67 @@ static int seen;
|
|||||||
static char delim = '=';
|
static char delim = '=';
|
||||||
static char key_delim = ' ';
|
static char key_delim = ' ';
|
||||||
static char term = '\n';
|
static char term = '\n';
|
||||||
static enum { T_RAW, T_INT, T_BOOL, T_BOOL_OR_INT } type = T_RAW;
|
|
||||||
|
static int use_global_config, use_system_config;
|
||||||
|
static const char *given_config_file;
|
||||||
|
static int actions, types;
|
||||||
|
static const char *get_color_slot, *get_colorbool_slot;
|
||||||
|
static int end_null;
|
||||||
|
|
||||||
|
#define ACTION_GET (1<<0)
|
||||||
|
#define ACTION_GET_ALL (1<<1)
|
||||||
|
#define ACTION_GET_REGEXP (1<<2)
|
||||||
|
#define ACTION_REPLACE_ALL (1<<3)
|
||||||
|
#define ACTION_ADD (1<<4)
|
||||||
|
#define ACTION_UNSET (1<<5)
|
||||||
|
#define ACTION_UNSET_ALL (1<<6)
|
||||||
|
#define ACTION_RENAME_SECTION (1<<7)
|
||||||
|
#define ACTION_REMOVE_SECTION (1<<8)
|
||||||
|
#define ACTION_LIST (1<<9)
|
||||||
|
#define ACTION_EDIT (1<<10)
|
||||||
|
#define ACTION_SET (1<<11)
|
||||||
|
#define ACTION_SET_ALL (1<<12)
|
||||||
|
#define ACTION_GET_COLOR (1<<13)
|
||||||
|
#define ACTION_GET_COLORBOOL (1<<14)
|
||||||
|
|
||||||
|
#define TYPE_BOOL (1<<0)
|
||||||
|
#define TYPE_INT (1<<1)
|
||||||
|
#define TYPE_BOOL_OR_INT (1<<2)
|
||||||
|
|
||||||
|
static struct option builtin_config_options[] = {
|
||||||
|
OPT_GROUP("Config file location"),
|
||||||
|
OPT_BOOLEAN(0, "global", &use_global_config, "use global config file"),
|
||||||
|
OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"),
|
||||||
|
OPT_STRING('f', "file", &given_config_file, "FILE", "use given config file"),
|
||||||
|
OPT_GROUP("Action"),
|
||||||
|
OPT_BIT(0, "get", &actions, "get value: name [value-regex]", ACTION_GET),
|
||||||
|
OPT_BIT(0, "get-all", &actions, "get all values: key [value-regex]", ACTION_GET_ALL),
|
||||||
|
OPT_BIT(0, "get-regexp", &actions, "get values for regexp: name-regex [value-regex]", ACTION_GET_REGEXP),
|
||||||
|
OPT_BIT(0, "replace-all", &actions, "replace all matching variables: name value [value_regex]", ACTION_REPLACE_ALL),
|
||||||
|
OPT_BIT(0, "add", &actions, "adds a new variable: name value", ACTION_ADD),
|
||||||
|
OPT_BIT(0, "unset", &actions, "removes a variable: name [value-regex]", ACTION_UNSET),
|
||||||
|
OPT_BIT(0, "unset-all", &actions, "removes all matches: name [value-regex]", ACTION_UNSET_ALL),
|
||||||
|
OPT_BIT(0, "rename-section", &actions, "rename section: old-name new-name", ACTION_RENAME_SECTION),
|
||||||
|
OPT_BIT(0, "remove-section", &actions, "remove a section: name", ACTION_REMOVE_SECTION),
|
||||||
|
OPT_BIT('l', "list", &actions, "list all", ACTION_LIST),
|
||||||
|
OPT_BIT('e', "edit", &actions, "opens an editor", ACTION_EDIT),
|
||||||
|
OPT_STRING(0, "get-color", &get_color_slot, "slot", "find the color configured: [default]"),
|
||||||
|
OPT_STRING(0, "get-colorbool", &get_colorbool_slot, "slot", "find the color setting: [stdout-is-tty]"),
|
||||||
|
OPT_GROUP("Type"),
|
||||||
|
OPT_BIT(0, "bool", &types, "value is \"true\" or \"false\"", TYPE_BOOL),
|
||||||
|
OPT_BIT(0, "int", &types, "value is decimal number", TYPE_INT),
|
||||||
|
OPT_BIT(0, "bool-or-int", &types, "value is --bool or --int", TYPE_BOOL_OR_INT),
|
||||||
|
OPT_GROUP("Other"),
|
||||||
|
OPT_BOOLEAN('z', "null", &end_null, "terminate values with NUL byte"),
|
||||||
|
OPT_END(),
|
||||||
|
};
|
||||||
|
|
||||||
|
static void check_argc(int argc, int min, int max) {
|
||||||
|
if (argc >= min && argc <= max)
|
||||||
|
return;
|
||||||
|
error("wrong number of arguments");
|
||||||
|
usage_with_options(builtin_config_usage, builtin_config_options);
|
||||||
|
}
|
||||||
|
|
||||||
static int show_all_config(const char *key_, const char *value_, void *cb)
|
static int show_all_config(const char *key_, const char *value_, void *cb)
|
||||||
{
|
{
|
||||||
@@ -49,11 +112,11 @@ static int show_config(const char *key_, const char *value_, void *cb)
|
|||||||
}
|
}
|
||||||
if (seen && !do_all)
|
if (seen && !do_all)
|
||||||
dup_error = 1;
|
dup_error = 1;
|
||||||
if (type == T_INT)
|
if (types == TYPE_INT)
|
||||||
sprintf(value, "%d", git_config_int(key_, value_?value_:""));
|
sprintf(value, "%d", git_config_int(key_, value_?value_:""));
|
||||||
else if (type == T_BOOL)
|
else if (types == TYPE_BOOL)
|
||||||
vptr = git_config_bool(key_, value_) ? "true" : "false";
|
vptr = git_config_bool(key_, value_) ? "true" : "false";
|
||||||
else if (type == T_BOOL_OR_INT) {
|
else if (types == TYPE_BOOL_OR_INT) {
|
||||||
int is_bool, v;
|
int is_bool, v;
|
||||||
v = git_config_bool_or_int(key_, value_, &is_bool);
|
v = git_config_bool_or_int(key_, value_, &is_bool);
|
||||||
if (is_bool)
|
if (is_bool)
|
||||||
@@ -152,18 +215,18 @@ static char *normalize_value(const char *key, const char *value)
|
|||||||
if (!value)
|
if (!value)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (type == T_RAW)
|
if (types == 0)
|
||||||
normalized = xstrdup(value);
|
normalized = xstrdup(value);
|
||||||
else {
|
else {
|
||||||
normalized = xmalloc(64);
|
normalized = xmalloc(64);
|
||||||
if (type == T_INT) {
|
if (types == TYPE_INT) {
|
||||||
int v = git_config_int(key, value);
|
int v = git_config_int(key, value);
|
||||||
sprintf(normalized, "%d", v);
|
sprintf(normalized, "%d", v);
|
||||||
}
|
}
|
||||||
else if (type == T_BOOL)
|
else if (types == TYPE_BOOL)
|
||||||
sprintf(normalized, "%s",
|
sprintf(normalized, "%s",
|
||||||
git_config_bool(key, value) ? "true" : "false");
|
git_config_bool(key, value) ? "true" : "false");
|
||||||
else if (type == T_BOOL_OR_INT) {
|
else if (types == TYPE_BOOL_OR_INT) {
|
||||||
int is_bool, v;
|
int is_bool, v;
|
||||||
v = git_config_bool_or_int(key, value, &is_bool);
|
v = git_config_bool_or_int(key, value, &is_bool);
|
||||||
if (!is_bool)
|
if (!is_bool)
|
||||||
@@ -178,6 +241,7 @@ static char *normalize_value(const char *key, const char *value)
|
|||||||
|
|
||||||
static int get_color_found;
|
static int get_color_found;
|
||||||
static const char *get_color_slot;
|
static const char *get_color_slot;
|
||||||
|
static const char *get_colorbool_slot;
|
||||||
static char parsed_color[COLOR_MAXLEN];
|
static char parsed_color[COLOR_MAXLEN];
|
||||||
|
|
||||||
static int git_get_color_config(const char *var, const char *value, void *cb)
|
static int git_get_color_config(const char *var, const char *value, void *cb)
|
||||||
@@ -191,29 +255,8 @@ static int git_get_color_config(const char *var, const char *value, void *cb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_color(int argc, const char **argv)
|
static void get_color(const char *def_color)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* grab the color setting for the given slot from the configuration,
|
|
||||||
* or parse the default value if missing, and return ANSI color
|
|
||||||
* escape sequence.
|
|
||||||
*
|
|
||||||
* e.g.
|
|
||||||
* git config --get-color color.diff.whitespace "blue reverse"
|
|
||||||
*/
|
|
||||||
const char *def_color = NULL;
|
|
||||||
|
|
||||||
switch (argc) {
|
|
||||||
default:
|
|
||||||
usage(git_config_set_usage);
|
|
||||||
case 2:
|
|
||||||
def_color = argv[1];
|
|
||||||
/* fallthru */
|
|
||||||
case 1:
|
|
||||||
get_color_slot = argv[0];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
get_color_found = 0;
|
get_color_found = 0;
|
||||||
parsed_color[0] = '\0';
|
parsed_color[0] = '\0';
|
||||||
git_config(git_get_color_config, NULL);
|
git_config(git_get_color_config, NULL);
|
||||||
@@ -222,7 +265,6 @@ static int get_color(int argc, const char **argv)
|
|||||||
color_parse(def_color, "command line", parsed_color);
|
color_parse(def_color, "command line", parsed_color);
|
||||||
|
|
||||||
fputs(parsed_color, stdout);
|
fputs(parsed_color, stdout);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stdout_is_tty;
|
static int stdout_is_tty;
|
||||||
@@ -231,7 +273,7 @@ static int get_diff_color_found;
|
|||||||
static int git_get_colorbool_config(const char *var, const char *value,
|
static int git_get_colorbool_config(const char *var, const char *value,
|
||||||
void *cb)
|
void *cb)
|
||||||
{
|
{
|
||||||
if (!strcmp(var, get_color_slot)) {
|
if (!strcmp(var, get_colorbool_slot)) {
|
||||||
get_colorbool_found =
|
get_colorbool_found =
|
||||||
git_config_colorbool(var, value, stdout_is_tty);
|
git_config_colorbool(var, value, stdout_is_tty);
|
||||||
}
|
}
|
||||||
@@ -246,191 +288,188 @@ static int git_get_colorbool_config(const char *var, const char *value,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_colorbool(int argc, const char **argv)
|
static int get_colorbool(int print)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* git config --get-colorbool <slot> [<stdout-is-tty>]
|
|
||||||
*
|
|
||||||
* returns "true" or "false" depending on how <slot>
|
|
||||||
* is configured.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (argc == 2)
|
|
||||||
stdout_is_tty = git_config_bool("command line", argv[1]);
|
|
||||||
else if (argc == 1)
|
|
||||||
stdout_is_tty = isatty(1);
|
|
||||||
else
|
|
||||||
usage(git_config_set_usage);
|
|
||||||
get_colorbool_found = -1;
|
get_colorbool_found = -1;
|
||||||
get_diff_color_found = -1;
|
get_diff_color_found = -1;
|
||||||
get_color_slot = argv[0];
|
|
||||||
git_config(git_get_colorbool_config, NULL);
|
git_config(git_get_colorbool_config, NULL);
|
||||||
|
|
||||||
if (get_colorbool_found < 0) {
|
if (get_colorbool_found < 0) {
|
||||||
if (!strcmp(get_color_slot, "color.diff"))
|
if (!strcmp(get_colorbool_slot, "color.diff"))
|
||||||
get_colorbool_found = get_diff_color_found;
|
get_colorbool_found = get_diff_color_found;
|
||||||
if (get_colorbool_found < 0)
|
if (get_colorbool_found < 0)
|
||||||
get_colorbool_found = git_use_color_default;
|
get_colorbool_found = git_use_color_default;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc == 1) {
|
if (print) {
|
||||||
return get_colorbool_found ? 0 : 1;
|
|
||||||
} else {
|
|
||||||
printf("%s\n", get_colorbool_found ? "true" : "false");
|
printf("%s\n", get_colorbool_found ? "true" : "false");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else
|
||||||
|
return get_colorbool_found ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_config(int argc, const char **argv, const char *prefix)
|
int cmd_config(int argc, const char **argv, const char *unused_prefix)
|
||||||
{
|
{
|
||||||
int nongit;
|
int nongit;
|
||||||
char *value;
|
char *value;
|
||||||
const char *file = setup_git_directory_gently(&nongit);
|
const char *prefix = setup_git_directory_gently(&nongit);
|
||||||
|
|
||||||
config_exclusive_filename = getenv(CONFIG_ENVIRONMENT);
|
config_exclusive_filename = getenv(CONFIG_ENVIRONMENT);
|
||||||
|
|
||||||
while (1 < argc) {
|
argc = parse_options(argc, argv, builtin_config_options, builtin_config_usage,
|
||||||
if (!strcmp(argv[1], "--int"))
|
PARSE_OPT_STOP_AT_NON_OPTION);
|
||||||
type = T_INT;
|
|
||||||
else if (!strcmp(argv[1], "--bool"))
|
if (use_global_config + use_system_config + !!given_config_file > 1) {
|
||||||
type = T_BOOL;
|
error("only one config file at a time.");
|
||||||
else if (!strcmp(argv[1], "--bool-or-int"))
|
usage_with_options(builtin_config_usage, builtin_config_options);
|
||||||
type = T_BOOL_OR_INT;
|
|
||||||
else if (!strcmp(argv[1], "--list") || !strcmp(argv[1], "-l")) {
|
|
||||||
if (argc != 2)
|
|
||||||
usage(git_config_set_usage);
|
|
||||||
if (git_config(show_all_config, NULL) < 0 &&
|
|
||||||
file && errno)
|
|
||||||
die("unable to read config file %s: %s", file,
|
|
||||||
strerror(errno));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (!strcmp(argv[1], "--global")) {
|
|
||||||
char *home = getenv("HOME");
|
|
||||||
if (home) {
|
|
||||||
char *user_config = xstrdup(mkpath("%s/.gitconfig", home));
|
|
||||||
config_exclusive_filename = user_config;
|
|
||||||
} else {
|
|
||||||
die("$HOME not set");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!strcmp(argv[1], "--system"))
|
|
||||||
config_exclusive_filename = git_etc_gitconfig();
|
|
||||||
else if (!strcmp(argv[1], "--file") || !strcmp(argv[1], "-f")) {
|
|
||||||
if (argc < 3)
|
|
||||||
usage(git_config_set_usage);
|
|
||||||
if (!is_absolute_path(argv[2]) && file)
|
|
||||||
file = prefix_filename(file, strlen(file),
|
|
||||||
argv[2]);
|
|
||||||
else
|
|
||||||
file = argv[2];
|
|
||||||
config_exclusive_filename = file;
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
}
|
|
||||||
else if (!strcmp(argv[1], "--null") || !strcmp(argv[1], "-z")) {
|
|
||||||
term = '\0';
|
|
||||||
delim = '\n';
|
|
||||||
key_delim = '\n';
|
|
||||||
}
|
|
||||||
else if (!strcmp(argv[1], "--rename-section")) {
|
|
||||||
int ret;
|
|
||||||
if (argc != 4)
|
|
||||||
usage(git_config_set_usage);
|
|
||||||
ret = git_config_rename_section(argv[2], argv[3]);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
if (ret == 0) {
|
|
||||||
fprintf(stderr, "No such section!\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (!strcmp(argv[1], "--remove-section")) {
|
|
||||||
int ret;
|
|
||||||
if (argc != 3)
|
|
||||||
usage(git_config_set_usage);
|
|
||||||
ret = git_config_rename_section(argv[2], NULL);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
if (ret == 0) {
|
|
||||||
fprintf(stderr, "No such section!\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
} else if (!strcmp(argv[1], "--get-color")) {
|
|
||||||
return get_color(argc-2, argv+2);
|
|
||||||
} else if (!strcmp(argv[1], "--get-colorbool")) {
|
|
||||||
return get_colorbool(argc-2, argv+2);
|
|
||||||
} else if (!strcmp(argv[1], "--edit") || !strcmp(argv[1], "-e")) {
|
|
||||||
if (argc != 2)
|
|
||||||
usage(git_config_set_usage);
|
|
||||||
git_config(git_default_config, NULL);
|
|
||||||
launch_editor(config_exclusive_filename ?
|
|
||||||
config_exclusive_filename : git_path("config"),
|
|
||||||
NULL, NULL);
|
|
||||||
return 0;
|
|
||||||
} else
|
|
||||||
break;
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (argc) {
|
if (use_global_config) {
|
||||||
case 2:
|
char *home = getenv("HOME");
|
||||||
return get_value(argv[1], NULL);
|
if (home) {
|
||||||
case 3:
|
char *user_config = xstrdup(mkpath("%s/.gitconfig", home));
|
||||||
if (!strcmp(argv[1], "--unset"))
|
config_exclusive_filename = user_config;
|
||||||
return git_config_set(argv[2], NULL);
|
|
||||||
else if (!strcmp(argv[1], "--unset-all"))
|
|
||||||
return git_config_set_multivar(argv[2], NULL, NULL, 1);
|
|
||||||
else if (!strcmp(argv[1], "--get"))
|
|
||||||
return get_value(argv[2], NULL);
|
|
||||||
else if (!strcmp(argv[1], "--get-all")) {
|
|
||||||
do_all = 1;
|
|
||||||
return get_value(argv[2], NULL);
|
|
||||||
} else if (!strcmp(argv[1], "--get-regexp")) {
|
|
||||||
show_keys = 1;
|
|
||||||
use_key_regexp = 1;
|
|
||||||
do_all = 1;
|
|
||||||
return get_value(argv[2], NULL);
|
|
||||||
} else {
|
} else {
|
||||||
value = normalize_value(argv[1], argv[2]);
|
die("$HOME not set");
|
||||||
return git_config_set(argv[1], value);
|
|
||||||
}
|
}
|
||||||
case 4:
|
|
||||||
if (!strcmp(argv[1], "--unset"))
|
|
||||||
return git_config_set_multivar(argv[2], NULL, argv[3], 0);
|
|
||||||
else if (!strcmp(argv[1], "--unset-all"))
|
|
||||||
return git_config_set_multivar(argv[2], NULL, argv[3], 1);
|
|
||||||
else if (!strcmp(argv[1], "--get"))
|
|
||||||
return get_value(argv[2], argv[3]);
|
|
||||||
else if (!strcmp(argv[1], "--get-all")) {
|
|
||||||
do_all = 1;
|
|
||||||
return get_value(argv[2], argv[3]);
|
|
||||||
} else if (!strcmp(argv[1], "--get-regexp")) {
|
|
||||||
show_keys = 1;
|
|
||||||
use_key_regexp = 1;
|
|
||||||
do_all = 1;
|
|
||||||
return get_value(argv[2], argv[3]);
|
|
||||||
} else if (!strcmp(argv[1], "--add")) {
|
|
||||||
value = normalize_value(argv[2], argv[3]);
|
|
||||||
return git_config_set_multivar(argv[2], value, "^$", 0);
|
|
||||||
} else if (!strcmp(argv[1], "--replace-all")) {
|
|
||||||
value = normalize_value(argv[2], argv[3]);
|
|
||||||
return git_config_set_multivar(argv[2], value, NULL, 1);
|
|
||||||
} else {
|
|
||||||
value = normalize_value(argv[1], argv[2]);
|
|
||||||
return git_config_set_multivar(argv[1], value, argv[3], 0);
|
|
||||||
}
|
|
||||||
case 5:
|
|
||||||
if (!strcmp(argv[1], "--replace-all")) {
|
|
||||||
value = normalize_value(argv[2], argv[3]);
|
|
||||||
return git_config_set_multivar(argv[2], value, argv[4], 1);
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
default:
|
|
||||||
usage(git_config_set_usage);
|
|
||||||
}
|
}
|
||||||
|
else if (use_system_config)
|
||||||
|
config_exclusive_filename = git_etc_gitconfig();
|
||||||
|
else if (given_config_file) {
|
||||||
|
if (!is_absolute_path(given_config_file) && prefix)
|
||||||
|
config_exclusive_filename = prefix_filename(prefix,
|
||||||
|
strlen(prefix),
|
||||||
|
argv[2]);
|
||||||
|
else
|
||||||
|
config_exclusive_filename = given_config_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end_null) {
|
||||||
|
term = '\0';
|
||||||
|
delim = '\n';
|
||||||
|
key_delim = '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HAS_MULTI_BITS(types)) {
|
||||||
|
error("only one type at a time.");
|
||||||
|
usage_with_options(builtin_config_usage, builtin_config_options);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_color_slot)
|
||||||
|
actions |= ACTION_GET_COLOR;
|
||||||
|
if (get_colorbool_slot)
|
||||||
|
actions |= ACTION_GET_COLORBOOL;
|
||||||
|
|
||||||
|
if ((get_color_slot || get_colorbool_slot) && types) {
|
||||||
|
error("--get-color and variable type are incoherent");
|
||||||
|
usage_with_options(builtin_config_usage, builtin_config_options);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HAS_MULTI_BITS(actions)) {
|
||||||
|
error("only one action at a time.");
|
||||||
|
usage_with_options(builtin_config_usage, builtin_config_options);
|
||||||
|
}
|
||||||
|
if (actions == 0)
|
||||||
|
switch (argc) {
|
||||||
|
case 1: actions = ACTION_GET; break;
|
||||||
|
case 2: actions = ACTION_SET; break;
|
||||||
|
case 3: actions = ACTION_SET_ALL; break;
|
||||||
|
default:
|
||||||
|
usage_with_options(builtin_config_usage, builtin_config_options);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actions == ACTION_LIST) {
|
||||||
|
check_argc(argc, 0, 0);
|
||||||
|
if (git_config(show_all_config, NULL) < 0) {
|
||||||
|
if (config_exclusive_filename)
|
||||||
|
die("unable to read config file %s: %s",
|
||||||
|
config_exclusive_filename, strerror(errno));
|
||||||
|
else
|
||||||
|
die("error processing config file(s)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (actions == ACTION_EDIT) {
|
||||||
|
check_argc(argc, 0, 0);
|
||||||
|
git_config(git_default_config, NULL);
|
||||||
|
launch_editor(config_exclusive_filename ?
|
||||||
|
config_exclusive_filename : git_path("config"),
|
||||||
|
NULL, NULL);
|
||||||
|
}
|
||||||
|
else if (actions == ACTION_SET) {
|
||||||
|
check_argc(argc, 2, 2);
|
||||||
|
value = normalize_value(argv[0], argv[1]);
|
||||||
|
return git_config_set(argv[0], value);
|
||||||
|
}
|
||||||
|
else if (actions == ACTION_SET_ALL) {
|
||||||
|
check_argc(argc, 2, 3);
|
||||||
|
value = normalize_value(argv[0], argv[1]);
|
||||||
|
return git_config_set_multivar(argv[0], value, argv[2], 0);
|
||||||
|
}
|
||||||
|
else if (actions == ACTION_ADD) {
|
||||||
|
check_argc(argc, 2, 2);
|
||||||
|
value = normalize_value(argv[0], argv[1]);
|
||||||
|
return git_config_set_multivar(argv[0], value, "^$", 0);
|
||||||
|
}
|
||||||
|
else if (actions == ACTION_REPLACE_ALL) {
|
||||||
|
check_argc(argc, 2, 3);
|
||||||
|
value = normalize_value(argv[0], argv[1]);
|
||||||
|
return git_config_set_multivar(argv[0], value, argv[2], 1);
|
||||||
|
}
|
||||||
|
else if (actions == ACTION_GET) {
|
||||||
|
check_argc(argc, 1, 2);
|
||||||
|
return get_value(argv[0], argv[1]);
|
||||||
|
}
|
||||||
|
else if (actions == ACTION_GET_ALL) {
|
||||||
|
do_all = 1;
|
||||||
|
check_argc(argc, 1, 2);
|
||||||
|
return get_value(argv[0], argv[1]);
|
||||||
|
}
|
||||||
|
else if (actions == ACTION_GET_REGEXP) {
|
||||||
|
show_keys = 1;
|
||||||
|
use_key_regexp = 1;
|
||||||
|
do_all = 1;
|
||||||
|
check_argc(argc, 1, 2);
|
||||||
|
return get_value(argv[0], argv[1]);
|
||||||
|
}
|
||||||
|
else if (actions == ACTION_UNSET) {
|
||||||
|
check_argc(argc, 1, 2);
|
||||||
|
if (argc == 2)
|
||||||
|
return git_config_set_multivar(argv[0], NULL, argv[1], 0);
|
||||||
|
else
|
||||||
|
return git_config_set(argv[0], NULL);
|
||||||
|
}
|
||||||
|
else if (actions == ACTION_UNSET_ALL) {
|
||||||
|
check_argc(argc, 1, 2);
|
||||||
|
return git_config_set_multivar(argv[0], NULL, argv[1], 1);
|
||||||
|
}
|
||||||
|
else if (actions == ACTION_RENAME_SECTION) {
|
||||||
|
int ret;
|
||||||
|
check_argc(argc, 2, 2);
|
||||||
|
ret = git_config_rename_section(argv[0], argv[1]);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
if (ret == 0)
|
||||||
|
die("No such section!");
|
||||||
|
}
|
||||||
|
else if (actions == ACTION_REMOVE_SECTION) {
|
||||||
|
int ret;
|
||||||
|
check_argc(argc, 1, 1);
|
||||||
|
ret = git_config_rename_section(argv[0], NULL);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
if (ret == 0)
|
||||||
|
die("No such section!");
|
||||||
|
}
|
||||||
|
else if (actions == ACTION_GET_COLOR) {
|
||||||
|
get_color(argv[0]);
|
||||||
|
}
|
||||||
|
else if (actions == ACTION_GET_COLORBOOL) {
|
||||||
|
if (argc == 1)
|
||||||
|
stdout_is_tty = git_config_bool("command line", argv[0]);
|
||||||
|
else if (argc == 0)
|
||||||
|
stdout_is_tty = isatty(1);
|
||||||
|
return get_colorbool(argc != 0);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -221,7 +221,8 @@ static void handle_commit(struct commit *commit, struct rev_info *rev)
|
|||||||
if (message)
|
if (message)
|
||||||
message += 2;
|
message += 2;
|
||||||
|
|
||||||
if (commit->parents) {
|
if (commit->parents &&
|
||||||
|
get_object_mark(&commit->parents->item->object) != 0) {
|
||||||
parse_commit(commit->parents->item);
|
parse_commit(commit->parents->item);
|
||||||
diff_tree_sha1(commit->parents->item->tree->object.sha1,
|
diff_tree_sha1(commit->parents->item->tree->object.sha1,
|
||||||
commit->tree->object.sha1, "", &rev->diffopt);
|
commit->tree->object.sha1, "", &rev->diffopt);
|
||||||
@@ -362,7 +363,10 @@ static void get_tags_and_duplicates(struct object_array *pending,
|
|||||||
break;
|
break;
|
||||||
case OBJ_TAG:
|
case OBJ_TAG:
|
||||||
tag = (struct tag *)e->item;
|
tag = (struct tag *)e->item;
|
||||||
|
|
||||||
|
/* handle nested tags */
|
||||||
while (tag && tag->object.type == OBJ_TAG) {
|
while (tag && tag->object.type == OBJ_TAG) {
|
||||||
|
parse_object(tag->object.sha1);
|
||||||
string_list_append(full_name, extra_refs)->util = tag;
|
string_list_append(full_name, extra_refs)->util = tag;
|
||||||
tag = (struct tag *)tag->tagged;
|
tag = (struct tag *)tag->tagged;
|
||||||
}
|
}
|
||||||
@@ -375,11 +379,17 @@ static void get_tags_and_duplicates(struct object_array *pending,
|
|||||||
case OBJ_BLOB:
|
case OBJ_BLOB:
|
||||||
handle_object(tag->object.sha1);
|
handle_object(tag->object.sha1);
|
||||||
continue;
|
continue;
|
||||||
|
default: /* OBJ_TAG (nested tags) is already handled */
|
||||||
|
warning("Tag points to object of unexpected type %s, skipping.",
|
||||||
|
typename(tag->object.type));
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
die ("Unexpected object of type %s",
|
warning("%s: Unexpected object of type %s, skipping.",
|
||||||
typename(e->item->type));
|
e->name,
|
||||||
|
typename(e->item->type));
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
if (commit->util)
|
if (commit->util)
|
||||||
/* more than one name for the same object */
|
/* more than one name for the same object */
|
||||||
|
|||||||
@@ -605,7 +605,7 @@ static struct ref *do_fetch_pack(int fd[2],
|
|||||||
/* When cloning, it is not unusual to have
|
/* When cloning, it is not unusual to have
|
||||||
* no common commit.
|
* no common commit.
|
||||||
*/
|
*/
|
||||||
fprintf(stderr, "warning: no common commits\n");
|
warning("no common commits");
|
||||||
|
|
||||||
if (get_pack(fd, pack_lockfile))
|
if (get_pack(fd, pack_lockfile))
|
||||||
die("git fetch-pack: fetch failed.");
|
die("git fetch-pack: fetch failed.");
|
||||||
@@ -800,15 +800,13 @@ struct ref *fetch_pack(struct fetch_pack_args *my_args,
|
|||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
mtime.sec = st.st_mtime;
|
mtime.sec = st.st_mtime;
|
||||||
#ifdef USE_NSEC
|
mtime.nsec = ST_MTIME_NSEC(st);
|
||||||
mtime.usec = st.st_mtim.usec;
|
|
||||||
#endif
|
|
||||||
if (stat(shallow, &st)) {
|
if (stat(shallow, &st)) {
|
||||||
if (mtime.sec)
|
if (mtime.sec)
|
||||||
die("shallow file was removed during fetch");
|
die("shallow file was removed during fetch");
|
||||||
} else if (st.st_mtime != mtime.sec
|
} else if (st.st_mtime != mtime.sec
|
||||||
#ifdef USE_NSEC
|
#ifdef USE_NSEC
|
||||||
|| st.st_mtim.usec != mtime.usec
|
|| ST_MTIME_NSEC(st) != mtime.nsec
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
die("shallow file was changed during fetch");
|
die("shallow file was changed during fetch");
|
||||||
|
|||||||
@@ -197,11 +197,7 @@ static int update_local_ref(struct ref *ref,
|
|||||||
struct commit *current = NULL, *updated;
|
struct commit *current = NULL, *updated;
|
||||||
enum object_type type;
|
enum object_type type;
|
||||||
struct branch *current_branch = branch_get(NULL);
|
struct branch *current_branch = branch_get(NULL);
|
||||||
const char *pretty_ref = ref->name + (
|
const char *pretty_ref = prettify_ref(ref);
|
||||||
!prefixcmp(ref->name, "refs/heads/") ? 11 :
|
|
||||||
!prefixcmp(ref->name, "refs/tags/") ? 10 :
|
|
||||||
!prefixcmp(ref->name, "refs/remotes/") ? 13 :
|
|
||||||
0);
|
|
||||||
|
|
||||||
*display = 0;
|
*display = 0;
|
||||||
type = sha1_object_info(ref->new_sha1, NULL);
|
type = sha1_object_info(ref->new_sha1, NULL);
|
||||||
@@ -544,7 +540,8 @@ static void check_not_current_branch(struct ref *ref_map)
|
|||||||
for (; ref_map; ref_map = ref_map->next)
|
for (; ref_map; ref_map = ref_map->next)
|
||||||
if (ref_map->peer_ref && !strcmp(current_branch->refname,
|
if (ref_map->peer_ref && !strcmp(current_branch->refname,
|
||||||
ref_map->peer_ref->name))
|
ref_map->peer_ref->name))
|
||||||
die("Refusing to fetch into current branch");
|
die("Refusing to fetch into current branch %s "
|
||||||
|
"of non-bare repository", current_branch->refname);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_fetch(struct transport *transport,
|
static int do_fetch(struct transport *transport,
|
||||||
@@ -636,6 +633,9 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
|
|||||||
else
|
else
|
||||||
remote = remote_get(argv[0]);
|
remote = remote_get(argv[0]);
|
||||||
|
|
||||||
|
if (!remote)
|
||||||
|
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 = 1;
|
||||||
@@ -648,9 +648,6 @@ 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 (!transport->url)
|
|
||||||
die("Where do you want to fetch from today?");
|
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
int j = 0;
|
int j = 0;
|
||||||
refs = xcalloc(argc + 1, sizeof(const char *));
|
refs = xcalloc(argc + 1, sizeof(const char *));
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ static const char * const builtin_gc_usage[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static int pack_refs = 1;
|
static int pack_refs = 1;
|
||||||
static int aggressive_window = -1;
|
static int aggressive_window = 250;
|
||||||
static int gc_auto_threshold = 6700;
|
static int gc_auto_threshold = 6700;
|
||||||
static int gc_auto_pack_limit = 50;
|
static int gc_auto_pack_limit = 50;
|
||||||
static const char *prune_expire = "2.weeks.ago";
|
static const char *prune_expire = "2.weeks.ago";
|
||||||
@@ -200,6 +200,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
|
|||||||
|
|
||||||
if (aggressive) {
|
if (aggressive) {
|
||||||
append_option(argv_repack, "-f", MAX_ADD);
|
append_option(argv_repack, "-f", MAX_ADD);
|
||||||
|
append_option(argv_repack, "--depth=250", MAX_ADD);
|
||||||
if (aggressive_window > 0) {
|
if (aggressive_window > 0) {
|
||||||
sprintf(buf, "--window=%d", aggressive_window);
|
sprintf(buf, "--window=%d", aggressive_window);
|
||||||
append_option(argv_repack, buf, MAX_ADD);
|
append_option(argv_repack, buf, MAX_ADD);
|
||||||
|
|||||||
@@ -22,6 +22,28 @@
|
|||||||
|
|
||||||
static int builtin_grep;
|
static int builtin_grep;
|
||||||
|
|
||||||
|
static int grep_config(const char *var, const char *value, void *cb)
|
||||||
|
{
|
||||||
|
struct grep_opt *opt = cb;
|
||||||
|
|
||||||
|
if (!strcmp(var, "grep.color") || !strcmp(var, "color.grep")) {
|
||||||
|
opt->color = git_config_colorbool(var, value, -1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!strcmp(var, "grep.color.external") ||
|
||||||
|
!strcmp(var, "color.grep.external")) {
|
||||||
|
return git_config_string(&(opt->color_external), var, value);
|
||||||
|
}
|
||||||
|
if (!strcmp(var, "grep.color.match") ||
|
||||||
|
!strcmp(var, "color.grep.match")) {
|
||||||
|
if (!value)
|
||||||
|
return config_error_nonbool(var);
|
||||||
|
color_parse(value, var, opt->color_match);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return git_color_default_config(var, value, cb);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* git grep pathspecs are somewhat different from diff-tree pathspecs;
|
* git grep pathspecs are somewhat different from diff-tree pathspecs;
|
||||||
* pathname wildcards are allowed.
|
* pathname wildcards are allowed.
|
||||||
@@ -269,6 +291,21 @@ static int flush_grep(struct grep_opt *opt,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void grep_add_color(struct strbuf *sb, const char *escape_seq)
|
||||||
|
{
|
||||||
|
size_t orig_len = sb->len;
|
||||||
|
|
||||||
|
while (*escape_seq) {
|
||||||
|
if (*escape_seq == 'm')
|
||||||
|
strbuf_addch(sb, ';');
|
||||||
|
else if (*escape_seq != '\033' && *escape_seq != '[')
|
||||||
|
strbuf_addch(sb, *escape_seq);
|
||||||
|
escape_seq++;
|
||||||
|
}
|
||||||
|
if (sb->len > orig_len && sb->buf[sb->len - 1] == ';')
|
||||||
|
strbuf_setlen(sb, sb->len - 1);
|
||||||
|
}
|
||||||
|
|
||||||
static int external_grep(struct grep_opt *opt, const char **paths, int cached)
|
static int external_grep(struct grep_opt *opt, const char **paths, int cached)
|
||||||
{
|
{
|
||||||
int i, nr, argc, hit, len, status;
|
int i, nr, argc, hit, len, status;
|
||||||
@@ -339,6 +376,23 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
|
|||||||
push_arg("-e");
|
push_arg("-e");
|
||||||
push_arg(p->pattern);
|
push_arg(p->pattern);
|
||||||
}
|
}
|
||||||
|
if (opt->color) {
|
||||||
|
struct strbuf sb = STRBUF_INIT;
|
||||||
|
|
||||||
|
grep_add_color(&sb, opt->color_match);
|
||||||
|
setenv("GREP_COLOR", sb.buf, 1);
|
||||||
|
|
||||||
|
strbuf_reset(&sb);
|
||||||
|
strbuf_addstr(&sb, "mt=");
|
||||||
|
grep_add_color(&sb, opt->color_match);
|
||||||
|
strbuf_addstr(&sb, ":sl=:cx=:fn=:ln=:bn=:se=");
|
||||||
|
setenv("GREP_COLORS", sb.buf, 1);
|
||||||
|
|
||||||
|
strbuf_release(&sb);
|
||||||
|
|
||||||
|
if (opt->color_external && strlen(opt->color_external) > 0)
|
||||||
|
push_arg(opt->color_external);
|
||||||
|
}
|
||||||
|
|
||||||
hit = 0;
|
hit = 0;
|
||||||
argc = nr;
|
argc = nr;
|
||||||
@@ -536,6 +590,12 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
|||||||
opt.pattern_tail = &opt.pattern_list;
|
opt.pattern_tail = &opt.pattern_list;
|
||||||
opt.regflags = REG_NEWLINE;
|
opt.regflags = REG_NEWLINE;
|
||||||
|
|
||||||
|
strcpy(opt.color_match, GIT_COLOR_RED GIT_COLOR_BOLD);
|
||||||
|
opt.color = -1;
|
||||||
|
git_config(grep_config, &opt);
|
||||||
|
if (opt.color == -1)
|
||||||
|
opt.color = git_use_color_default;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there is no -- then the paths must exist in the working
|
* If there is no -- then the paths must exist in the working
|
||||||
* tree. If there is no explicit pattern specified with -e or
|
* tree. If there is no explicit pattern specified with -e or
|
||||||
@@ -732,6 +792,14 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
|||||||
opt.relative = 0;
|
opt.relative = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!strcmp("--color", arg)) {
|
||||||
|
opt.color = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strcmp("--no-color", arg)) {
|
||||||
|
opt.color = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!strcmp("--", arg)) {
|
if (!strcmp("--", arg)) {
|
||||||
/* later processing wants to have this at argv[1] */
|
/* later processing wants to have this at argv[1] */
|
||||||
argv--;
|
argv--;
|
||||||
@@ -757,6 +825,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opt.color && !opt.color_external)
|
||||||
|
builtin_grep = 1;
|
||||||
if (!opt.pattern_list)
|
if (!opt.pattern_list)
|
||||||
die("no pattern given.");
|
die("no pattern given.");
|
||||||
if ((opt.regflags != REG_NEWLINE) && opt.fixed)
|
if ((opt.regflags != REG_NEWLINE) && opt.fixed)
|
||||||
|
|||||||
@@ -130,8 +130,7 @@ static void copy_templates(const char *template_dir)
|
|||||||
}
|
}
|
||||||
dir = opendir(template_path);
|
dir = opendir(template_path);
|
||||||
if (!dir) {
|
if (!dir) {
|
||||||
fprintf(stderr, "warning: templates not found %s\n",
|
warning("templates not found %s", template_dir);
|
||||||
template_dir);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,8 +143,8 @@ static void copy_templates(const char *template_dir)
|
|||||||
|
|
||||||
if (repository_format_version &&
|
if (repository_format_version &&
|
||||||
repository_format_version != GIT_REPO_VERSION) {
|
repository_format_version != GIT_REPO_VERSION) {
|
||||||
fprintf(stderr, "warning: not copying templates of "
|
warning("not copying templates of "
|
||||||
"a wrong format version %d from '%s'\n",
|
"a wrong format version %d from '%s'",
|
||||||
repository_format_version,
|
repository_format_version,
|
||||||
template_dir);
|
template_dir);
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
|
|||||||
@@ -573,7 +573,7 @@ static FILE *realstdout = NULL;
|
|||||||
static const char *output_directory = NULL;
|
static const char *output_directory = NULL;
|
||||||
static int outdir_offset;
|
static int outdir_offset;
|
||||||
|
|
||||||
static int reopen_stdout(const char *oneline, int nr, int total)
|
static int reopen_stdout(const char *oneline, int nr, struct rev_info *rev)
|
||||||
{
|
{
|
||||||
char filename[PATH_MAX];
|
char filename[PATH_MAX];
|
||||||
int len = 0;
|
int len = 0;
|
||||||
@@ -598,7 +598,9 @@ static int reopen_stdout(const char *oneline, int nr, int total)
|
|||||||
strcpy(filename + len, fmt_patch_suffix);
|
strcpy(filename + len, fmt_patch_suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(realstdout, "%s\n", filename + outdir_offset);
|
if (!DIFF_OPT_TST(&rev->diffopt, QUIET))
|
||||||
|
fprintf(realstdout, "%s\n", filename + outdir_offset);
|
||||||
|
|
||||||
if (freopen(filename, "w", stdout) == NULL)
|
if (freopen(filename, "w", stdout) == NULL)
|
||||||
return error("Cannot open patch file %s",filename);
|
return error("Cannot open patch file %s",filename);
|
||||||
|
|
||||||
@@ -687,7 +689,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
|
|||||||
die("Cover letter needs email format");
|
die("Cover letter needs email format");
|
||||||
|
|
||||||
if (!use_stdout && reopen_stdout(numbered_files ?
|
if (!use_stdout && reopen_stdout(numbered_files ?
|
||||||
NULL : "cover-letter", 0, rev->total))
|
NULL : "cover-letter", 0, rev))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
head_sha1 = sha1_to_hex(head->object.sha1);
|
head_sha1 = sha1_to_hex(head->object.sha1);
|
||||||
@@ -916,6 +918,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
|||||||
cover_letter = 1;
|
cover_letter = 1;
|
||||||
else if (!strcmp(argv[i], "--no-binary"))
|
else if (!strcmp(argv[i], "--no-binary"))
|
||||||
no_binary_diff = 1;
|
no_binary_diff = 1;
|
||||||
|
else if (!prefixcmp(argv[i], "--add-header="))
|
||||||
|
add_header(argv[i] + 13);
|
||||||
else
|
else
|
||||||
argv[j++] = argv[i];
|
argv[j++] = argv[i];
|
||||||
}
|
}
|
||||||
@@ -956,8 +960,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
|||||||
die ("-n and -k are mutually exclusive.");
|
die ("-n and -k are mutually exclusive.");
|
||||||
if (keep_subject && subject_prefix)
|
if (keep_subject && subject_prefix)
|
||||||
die ("--subject-prefix and -k are mutually exclusive.");
|
die ("--subject-prefix and -k are mutually exclusive.");
|
||||||
if (numbered_files && use_stdout)
|
|
||||||
die ("--numbered-files and --stdout are mutually exclusive.");
|
|
||||||
|
|
||||||
argc = setup_revisions(argc, argv, &rev, "HEAD");
|
argc = setup_revisions(argc, argv, &rev, "HEAD");
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
@@ -1106,7 +1108,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
|||||||
}
|
}
|
||||||
if (!use_stdout && reopen_stdout(numbered_files ? NULL :
|
if (!use_stdout && reopen_stdout(numbered_files ? NULL :
|
||||||
get_oneline_for_filename(commit, keep_subject),
|
get_oneline_for_filename(commit, keep_subject),
|
||||||
rev.nr, rev.total))
|
rev.nr, &rev))
|
||||||
die("Failed to create output files");
|
die("Failed to create output files");
|
||||||
shown = log_tree_commit(&rev, commit);
|
shown = log_tree_commit(&rev, commit);
|
||||||
free(commit->buffer);
|
free(commit->buffer);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "dir.h"
|
#include "dir.h"
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
|
#include "parse-options.h"
|
||||||
|
|
||||||
static int abbrev;
|
static int abbrev;
|
||||||
static int show_deleted;
|
static int show_deleted;
|
||||||
@@ -28,6 +29,7 @@ static const char **pathspec;
|
|||||||
static int error_unmatch;
|
static int error_unmatch;
|
||||||
static char *ps_matched;
|
static char *ps_matched;
|
||||||
static const char *with_tree;
|
static const char *with_tree;
|
||||||
|
static int exc_given;
|
||||||
|
|
||||||
static const char *tag_cached = "";
|
static const char *tag_cached = "";
|
||||||
static const char *tag_unmerged = "";
|
static const char *tag_unmerged = "";
|
||||||
@@ -174,7 +176,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) != dir->show_ignored)
|
if (excluded(dir, ce->name, &dtype) !=
|
||||||
|
!!(dir->flags & DIR_SHOW_IGNORED))
|
||||||
continue;
|
continue;
|
||||||
if (show_unmerged && !ce_stage(ce))
|
if (show_unmerged && !ce_stage(ce))
|
||||||
continue;
|
continue;
|
||||||
@@ -189,7 +192,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) != dir->show_ignored)
|
if (excluded(dir, ce->name, &dtype) !=
|
||||||
|
!!(dir->flags & DIR_SHOW_IGNORED))
|
||||||
continue;
|
continue;
|
||||||
if (ce->ce_flags & CE_UPDATE)
|
if (ce->ce_flags & CE_UPDATE)
|
||||||
continue;
|
continue;
|
||||||
@@ -374,156 +378,139 @@ int report_path_error(const char *ps_matched, const char **pathspec, int prefix_
|
|||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char ls_files_usage[] =
|
static const char * const ls_files_usage[] = {
|
||||||
"git ls-files [-z] [-t] [-v] (--[cached|deleted|others|stage|unmerged|killed|modified])* "
|
"git ls-files [options] [<file>]*",
|
||||||
"[ --ignored ] [--exclude=<pattern>] [--exclude-from=<file>] "
|
NULL
|
||||||
"[ --exclude-per-directory=<filename> ] [--exclude-standard] "
|
};
|
||||||
"[--full-name] [--abbrev] [--] [<file>]*";
|
|
||||||
|
static int option_parse_z(const struct option *opt,
|
||||||
|
const char *arg, int unset)
|
||||||
|
{
|
||||||
|
line_terminator = unset ? '\n' : '\0';
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int option_parse_exclude(const struct option *opt,
|
||||||
|
const char *arg, int unset)
|
||||||
|
{
|
||||||
|
struct exclude_list *list = opt->value;
|
||||||
|
|
||||||
|
exc_given = 1;
|
||||||
|
add_exclude(arg, "", 0, list);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int option_parse_exclude_from(const struct option *opt,
|
||||||
|
const char *arg, int unset)
|
||||||
|
{
|
||||||
|
struct dir_struct *dir = opt->value;
|
||||||
|
|
||||||
|
exc_given = 1;
|
||||||
|
add_excludes_from_file(dir, arg);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int option_parse_exclude_standard(const struct option *opt,
|
||||||
|
const char *arg, int unset)
|
||||||
|
{
|
||||||
|
struct dir_struct *dir = opt->value;
|
||||||
|
|
||||||
|
exc_given = 1;
|
||||||
|
setup_standard_excludes(dir);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int cmd_ls_files(int argc, const char **argv, const char *prefix)
|
int cmd_ls_files(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int i;
|
int require_work_tree = 0, show_tag = 0;
|
||||||
int exc_given = 0, require_work_tree = 0;
|
|
||||||
struct dir_struct dir;
|
struct dir_struct dir;
|
||||||
|
struct option builtin_ls_files_options[] = {
|
||||||
|
{ OPTION_CALLBACK, 'z', NULL, NULL, NULL,
|
||||||
|
"paths are separated with NUL character",
|
||||||
|
PARSE_OPT_NOARG, option_parse_z },
|
||||||
|
OPT_BOOLEAN('t', NULL, &show_tag,
|
||||||
|
"identify the file status with tags"),
|
||||||
|
OPT_BOOLEAN('v', NULL, &show_valid_bit,
|
||||||
|
"use lowercase letters for 'assume unchanged' files"),
|
||||||
|
OPT_BOOLEAN('c', "cached", &show_cached,
|
||||||
|
"show cached files in the output (default)"),
|
||||||
|
OPT_BOOLEAN('d', "deleted", &show_deleted,
|
||||||
|
"show deleted files in the output"),
|
||||||
|
OPT_BOOLEAN('m', "modified", &show_modified,
|
||||||
|
"show modified files in the output"),
|
||||||
|
OPT_BOOLEAN('o', "others", &show_others,
|
||||||
|
"show other files in the output"),
|
||||||
|
OPT_BIT('i', "ignored", &dir.flags,
|
||||||
|
"show ignored files in the output",
|
||||||
|
DIR_SHOW_IGNORED),
|
||||||
|
OPT_BOOLEAN('s', "stage", &show_stage,
|
||||||
|
"show staged contents' object name in the output"),
|
||||||
|
OPT_BOOLEAN('k', "killed", &show_killed,
|
||||||
|
"show files on the filesystem that need to be removed"),
|
||||||
|
OPT_BIT(0, "directory", &dir.flags,
|
||||||
|
"show 'other' directories' name only",
|
||||||
|
DIR_SHOW_OTHER_DIRECTORIES),
|
||||||
|
OPT_BIT(0, "no-empty-directory", &dir.flags,
|
||||||
|
"don't show empty directories",
|
||||||
|
DIR_HIDE_EMPTY_DIRECTORIES),
|
||||||
|
OPT_BOOLEAN('u', "unmerged", &show_unmerged,
|
||||||
|
"show unmerged files in the output"),
|
||||||
|
{ OPTION_CALLBACK, 'x', "exclude", &dir.exclude_list[EXC_CMDL], "pattern",
|
||||||
|
"skip files matching pattern",
|
||||||
|
0, option_parse_exclude },
|
||||||
|
{ OPTION_CALLBACK, 'X', "exclude-from", &dir, "file",
|
||||||
|
"exclude patterns are read from <file>",
|
||||||
|
0, option_parse_exclude_from },
|
||||||
|
OPT_STRING(0, "exclude-per-directory", &dir.exclude_per_dir, "file",
|
||||||
|
"read additional per-directory exclude patterns in <file>"),
|
||||||
|
{ OPTION_CALLBACK, 0, "exclude-standard", &dir, NULL,
|
||||||
|
"add the standard git exclusions",
|
||||||
|
PARSE_OPT_NOARG, option_parse_exclude_standard },
|
||||||
|
{ OPTION_SET_INT, 0, "full-name", &prefix_offset, NULL,
|
||||||
|
"make the output relative to the project top directory",
|
||||||
|
PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL },
|
||||||
|
OPT_BOOLEAN(0, "error-unmatch", &error_unmatch,
|
||||||
|
"if any <file> is not in the index, treat this as an error"),
|
||||||
|
OPT_STRING(0, "with-tree", &with_tree, "tree-ish",
|
||||||
|
"pretend that paths removed since <tree-ish> are still present"),
|
||||||
|
OPT__ABBREV(&abbrev),
|
||||||
|
OPT_END()
|
||||||
|
};
|
||||||
|
|
||||||
memset(&dir, 0, sizeof(dir));
|
memset(&dir, 0, sizeof(dir));
|
||||||
if (prefix)
|
if (prefix)
|
||||||
prefix_offset = strlen(prefix);
|
prefix_offset = strlen(prefix);
|
||||||
git_config(git_default_config, NULL);
|
git_config(git_default_config, NULL);
|
||||||
|
|
||||||
for (i = 1; i < argc; i++) {
|
argc = parse_options(argc, argv, builtin_ls_files_options,
|
||||||
const char *arg = argv[i];
|
ls_files_usage, 0);
|
||||||
|
if (show_tag || show_valid_bit) {
|
||||||
if (!strcmp(arg, "--")) {
|
tag_cached = "H ";
|
||||||
i++;
|
tag_unmerged = "M ";
|
||||||
break;
|
tag_removed = "R ";
|
||||||
}
|
tag_modified = "C ";
|
||||||
if (!strcmp(arg, "-z")) {
|
tag_other = "? ";
|
||||||
line_terminator = 0;
|
tag_killed = "K ";
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(arg, "-t") || !strcmp(arg, "-v")) {
|
|
||||||
tag_cached = "H ";
|
|
||||||
tag_unmerged = "M ";
|
|
||||||
tag_removed = "R ";
|
|
||||||
tag_modified = "C ";
|
|
||||||
tag_other = "? ";
|
|
||||||
tag_killed = "K ";
|
|
||||||
if (arg[1] == 'v')
|
|
||||||
show_valid_bit = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(arg, "-c") || !strcmp(arg, "--cached")) {
|
|
||||||
show_cached = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(arg, "-d") || !strcmp(arg, "--deleted")) {
|
|
||||||
show_deleted = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(arg, "-m") || !strcmp(arg, "--modified")) {
|
|
||||||
show_modified = 1;
|
|
||||||
require_work_tree = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(arg, "-o") || !strcmp(arg, "--others")) {
|
|
||||||
show_others = 1;
|
|
||||||
require_work_tree = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(arg, "-i") || !strcmp(arg, "--ignored")) {
|
|
||||||
dir.show_ignored = 1;
|
|
||||||
require_work_tree = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(arg, "-s") || !strcmp(arg, "--stage")) {
|
|
||||||
show_stage = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(arg, "-k") || !strcmp(arg, "--killed")) {
|
|
||||||
show_killed = 1;
|
|
||||||
require_work_tree = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(arg, "--directory")) {
|
|
||||||
dir.show_other_directories = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(arg, "--no-empty-directory")) {
|
|
||||||
dir.hide_empty_directories = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(arg, "-u") || !strcmp(arg, "--unmerged")) {
|
|
||||||
/* There's no point in showing unmerged unless
|
|
||||||
* you also show the stage information.
|
|
||||||
*/
|
|
||||||
show_stage = 1;
|
|
||||||
show_unmerged = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(arg, "-x") && i+1 < argc) {
|
|
||||||
exc_given = 1;
|
|
||||||
add_exclude(argv[++i], "", 0, &dir.exclude_list[EXC_CMDL]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!prefixcmp(arg, "--exclude=")) {
|
|
||||||
exc_given = 1;
|
|
||||||
add_exclude(arg+10, "", 0, &dir.exclude_list[EXC_CMDL]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(arg, "-X") && i+1 < argc) {
|
|
||||||
exc_given = 1;
|
|
||||||
add_excludes_from_file(&dir, argv[++i]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!prefixcmp(arg, "--exclude-from=")) {
|
|
||||||
exc_given = 1;
|
|
||||||
add_excludes_from_file(&dir, arg+15);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!prefixcmp(arg, "--exclude-per-directory=")) {
|
|
||||||
exc_given = 1;
|
|
||||||
dir.exclude_per_dir = arg + 24;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(arg, "--exclude-standard")) {
|
|
||||||
exc_given = 1;
|
|
||||||
setup_standard_excludes(&dir);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(arg, "--full-name")) {
|
|
||||||
prefix_offset = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(arg, "--error-unmatch")) {
|
|
||||||
error_unmatch = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!prefixcmp(arg, "--with-tree=")) {
|
|
||||||
with_tree = arg + 12;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!prefixcmp(arg, "--abbrev=")) {
|
|
||||||
abbrev = strtoul(arg+9, NULL, 10);
|
|
||||||
if (abbrev && abbrev < MINIMUM_ABBREV)
|
|
||||||
abbrev = MINIMUM_ABBREV;
|
|
||||||
else if (abbrev > 40)
|
|
||||||
abbrev = 40;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(arg, "--abbrev")) {
|
|
||||||
abbrev = DEFAULT_ABBREV;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (*arg == '-')
|
|
||||||
usage(ls_files_usage);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
if (show_modified || show_others || show_deleted || (dir.flags & DIR_SHOW_IGNORED) || show_killed)
|
||||||
|
require_work_tree = 1;
|
||||||
|
if (show_unmerged)
|
||||||
|
/*
|
||||||
|
* There's no point in showing unmerged unless
|
||||||
|
* you also show the stage information.
|
||||||
|
*/
|
||||||
|
show_stage = 1;
|
||||||
|
if (dir.exclude_per_dir)
|
||||||
|
exc_given = 1;
|
||||||
|
|
||||||
if (require_work_tree && !is_inside_work_tree())
|
if (require_work_tree && !is_inside_work_tree())
|
||||||
setup_work_tree();
|
setup_work_tree();
|
||||||
|
|
||||||
pathspec = get_pathspec(prefix, argv + i);
|
pathspec = get_pathspec(prefix, argv);
|
||||||
|
|
||||||
/* be nice with submodule patsh ending in a slash */
|
/* be nice with submodule patsh ending in a slash */
|
||||||
read_cache();
|
read_cache();
|
||||||
@@ -542,7 +529,7 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
|
|||||||
ps_matched = xcalloc(1, num);
|
ps_matched = xcalloc(1, num);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dir.show_ignored && !exc_given) {
|
if ((dir.flags & DIR_SHOW_IGNORED) && !exc_given) {
|
||||||
fprintf(stderr, "%s: --ignored needs some exclude pattern\n",
|
fprintf(stderr, "%s: --ignored needs some exclude pattern\n",
|
||||||
argv[0]);
|
argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen,
|
|||||||
{
|
{
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
const char *type = blob_type;
|
const char *type = blob_type;
|
||||||
unsigned long size;
|
|
||||||
|
|
||||||
if (S_ISGITLINK(mode)) {
|
if (S_ISGITLINK(mode)) {
|
||||||
/*
|
/*
|
||||||
@@ -90,17 +89,20 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen,
|
|||||||
|
|
||||||
if (!(ls_options & LS_NAME_ONLY)) {
|
if (!(ls_options & LS_NAME_ONLY)) {
|
||||||
if (ls_options & LS_SHOW_SIZE) {
|
if (ls_options & LS_SHOW_SIZE) {
|
||||||
|
char size_text[24];
|
||||||
if (!strcmp(type, blob_type)) {
|
if (!strcmp(type, blob_type)) {
|
||||||
sha1_object_info(sha1, &size);
|
unsigned long size;
|
||||||
printf("%06o %s %s %7lu\t", mode, type,
|
if (sha1_object_info(sha1, &size) == OBJ_BAD)
|
||||||
abbrev ? find_unique_abbrev(sha1, abbrev)
|
strcpy(size_text, "BAD");
|
||||||
: sha1_to_hex(sha1),
|
else
|
||||||
size);
|
snprintf(size_text, sizeof(size_text),
|
||||||
|
"%lu", size);
|
||||||
} else
|
} else
|
||||||
printf("%06o %s %s %7c\t", mode, type,
|
strcpy(size_text, "-");
|
||||||
abbrev ? find_unique_abbrev(sha1, abbrev)
|
printf("%06o %s %s %7s\t", mode, type,
|
||||||
: sha1_to_hex(sha1),
|
abbrev ? find_unique_abbrev(sha1, abbrev)
|
||||||
'-');
|
: sha1_to_hex(sha1),
|
||||||
|
size_text);
|
||||||
} else
|
} else
|
||||||
printf("%06o %s %s\t", mode, type,
|
printf("%06o %s %s\t", mode, type,
|
||||||
abbrev ? find_unique_abbrev(sha1, abbrev)
|
abbrev ? find_unique_abbrev(sha1, abbrev)
|
||||||
|
|||||||
@@ -636,7 +636,7 @@ static int checkout_fast_forward(unsigned char *head, unsigned char *remote)
|
|||||||
memset(&opts, 0, sizeof(opts));
|
memset(&opts, 0, sizeof(opts));
|
||||||
memset(&t, 0, sizeof(t));
|
memset(&t, 0, sizeof(t));
|
||||||
memset(&dir, 0, sizeof(dir));
|
memset(&dir, 0, sizeof(dir));
|
||||||
dir.show_ignored = 1;
|
dir.flags |= DIR_SHOW_IGNORED;
|
||||||
dir.exclude_per_dir = ".gitignore";
|
dir.exclude_per_dir = ".gitignore";
|
||||||
opts.dir = &dir;
|
opts.dir = &dir;
|
||||||
|
|
||||||
|
|||||||
@@ -1293,7 +1293,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
|
|||||||
max_size = trg_entry->delta_size;
|
max_size = trg_entry->delta_size;
|
||||||
ref_depth = trg->depth;
|
ref_depth = trg->depth;
|
||||||
}
|
}
|
||||||
max_size = max_size * (max_depth - src->depth) /
|
max_size = (uint64_t)max_size * (max_depth - src->depth) /
|
||||||
(max_depth - ref_depth + 1);
|
(max_depth - ref_depth + 1);
|
||||||
if (max_size == 0)
|
if (max_size == 0)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1966,7 +1966,7 @@ static void add_objects_in_unpacked_packs(struct rev_info *revs)
|
|||||||
const unsigned char *sha1;
|
const unsigned char *sha1;
|
||||||
struct object *o;
|
struct object *o;
|
||||||
|
|
||||||
if (p->pack_keep)
|
if (!p->pack_local || p->pack_keep)
|
||||||
continue;
|
continue;
|
||||||
if (open_pack_index(p))
|
if (open_pack_index(p))
|
||||||
die("cannot open pack index");
|
die("cannot open pack index");
|
||||||
@@ -1995,6 +1995,29 @@ static void add_objects_in_unpacked_packs(struct rev_info *revs)
|
|||||||
free(in_pack.array);
|
free(in_pack.array);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int has_sha1_pack_kept_or_nonlocal(const unsigned char *sha1)
|
||||||
|
{
|
||||||
|
static struct packed_git *last_found = (void *)1;
|
||||||
|
struct packed_git *p;
|
||||||
|
|
||||||
|
p = (last_found != (void *)1) ? last_found : packed_git;
|
||||||
|
|
||||||
|
while (p) {
|
||||||
|
if ((!p->pack_local || p->pack_keep) &&
|
||||||
|
find_pack_entry_one(sha1, p)) {
|
||||||
|
last_found = p;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (p == last_found)
|
||||||
|
p = packed_git;
|
||||||
|
else
|
||||||
|
p = p->next;
|
||||||
|
if (p == last_found)
|
||||||
|
p = p->next;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void loosen_unused_packed_objects(struct rev_info *revs)
|
static void loosen_unused_packed_objects(struct rev_info *revs)
|
||||||
{
|
{
|
||||||
struct packed_git *p;
|
struct packed_git *p;
|
||||||
@@ -2002,7 +2025,7 @@ static void loosen_unused_packed_objects(struct rev_info *revs)
|
|||||||
const unsigned char *sha1;
|
const unsigned char *sha1;
|
||||||
|
|
||||||
for (p = packed_git; p; p = p->next) {
|
for (p = packed_git; p; p = p->next) {
|
||||||
if (p->pack_keep)
|
if (!p->pack_local || p->pack_keep)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (open_pack_index(p))
|
if (open_pack_index(p))
|
||||||
@@ -2010,7 +2033,8 @@ static void loosen_unused_packed_objects(struct rev_info *revs)
|
|||||||
|
|
||||||
for (i = 0; i < p->num_objects; i++) {
|
for (i = 0; i < p->num_objects; i++) {
|
||||||
sha1 = nth_packed_object_sha1(p, i);
|
sha1 = nth_packed_object_sha1(p, i);
|
||||||
if (!locate_object_entry(sha1))
|
if (!locate_object_entry(sha1) &&
|
||||||
|
!has_sha1_pack_kept_or_nonlocal(sha1))
|
||||||
if (force_object_loose(sha1, p->mtime))
|
if (force_object_loose(sha1, p->mtime))
|
||||||
die("unable to force loose object");
|
die("unable to force loose object");
|
||||||
}
|
}
|
||||||
@@ -2200,7 +2224,6 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!strcmp("--unpacked", arg) ||
|
if (!strcmp("--unpacked", arg) ||
|
||||||
!strcmp("--kept-pack-only", arg) ||
|
|
||||||
!strcmp("--reflog", arg) ||
|
!strcmp("--reflog", arg) ||
|
||||||
!strcmp("--all", arg)) {
|
!strcmp("--all", arg)) {
|
||||||
use_internal_rev_list = 1;
|
use_internal_rev_list = 1;
|
||||||
|
|||||||
@@ -48,13 +48,81 @@ static void set_refspecs(const char **refs, int nr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setup_push_tracking(void)
|
||||||
|
{
|
||||||
|
struct strbuf refspec = STRBUF_INIT;
|
||||||
|
struct branch *branch = branch_get(NULL);
|
||||||
|
if (!branch)
|
||||||
|
die("You are not currently on a branch.");
|
||||||
|
if (!branch->merge_nr)
|
||||||
|
die("The current branch %s is not tracking anything.",
|
||||||
|
branch->name);
|
||||||
|
if (branch->merge_nr != 1)
|
||||||
|
die("The current branch %s is tracking multiple branches, "
|
||||||
|
"refusing to push.", branch->name);
|
||||||
|
strbuf_addf(&refspec, "%s:%s", branch->name, branch->merge[0]->src);
|
||||||
|
add_refspec(refspec.buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *warn_unconfigured_push_msg[] = {
|
||||||
|
"You did not specify any refspecs to push, and the current remote",
|
||||||
|
"has not configured any push refspecs. The default action in this",
|
||||||
|
"case is to push all matching refspecs, that is, all branches",
|
||||||
|
"that exist both locally and remotely will be updated. This may",
|
||||||
|
"not necessarily be what you want to happen.",
|
||||||
|
"",
|
||||||
|
"You can specify what action you want to take in this case, and",
|
||||||
|
"avoid seeing this message again, by configuring 'push.default' to:",
|
||||||
|
" 'nothing' : Do not push anything",
|
||||||
|
" 'matching' : Push all matching branches (default)",
|
||||||
|
" 'tracking' : Push the current branch to whatever it is tracking",
|
||||||
|
" 'current' : Push the current branch"
|
||||||
|
};
|
||||||
|
|
||||||
|
static void warn_unconfigured_push(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < ARRAY_SIZE(warn_unconfigured_push_msg); i++)
|
||||||
|
warning("%s", warn_unconfigured_push_msg[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setup_default_push_refspecs(void)
|
||||||
|
{
|
||||||
|
git_config(git_default_config, NULL);
|
||||||
|
switch (push_default) {
|
||||||
|
case PUSH_DEFAULT_UNSPECIFIED:
|
||||||
|
warn_unconfigured_push();
|
||||||
|
/* fallthrough */
|
||||||
|
|
||||||
|
case PUSH_DEFAULT_MATCHING:
|
||||||
|
add_refspec(":");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PUSH_DEFAULT_TRACKING:
|
||||||
|
setup_push_tracking();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PUSH_DEFAULT_CURRENT:
|
||||||
|
add_refspec("HEAD");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PUSH_DEFAULT_NOTHING:
|
||||||
|
die("You didn't specify any refspecs to push, and "
|
||||||
|
"push.default is \"nothing\".");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int do_push(const char *repo, int flags)
|
static int do_push(const char *repo, int flags)
|
||||||
{
|
{
|
||||||
int i, errs;
|
int i, errs;
|
||||||
struct remote *remote = remote_get(repo);
|
struct remote *remote = remote_get(repo);
|
||||||
|
|
||||||
if (!remote)
|
if (!remote) {
|
||||||
die("bad repository '%s'", repo);
|
if (repo)
|
||||||
|
die("bad repository '%s'", repo);
|
||||||
|
die("No destination configured to push to.");
|
||||||
|
}
|
||||||
|
|
||||||
if (remote->mirror)
|
if (remote->mirror)
|
||||||
flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE);
|
flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE);
|
||||||
@@ -76,11 +144,12 @@ static int do_push(const char *repo, int flags)
|
|||||||
return error("--all and --mirror are incompatible");
|
return error("--all and --mirror are incompatible");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!refspec
|
if (!refspec && !(flags & TRANSPORT_PUSH_ALL)) {
|
||||||
&& !(flags & TRANSPORT_PUSH_ALL)
|
if (remote->push_refspec_nr) {
|
||||||
&& remote->push_refspec_nr) {
|
refspec = remote->push_refspec;
|
||||||
refspec = remote->push_refspec;
|
refspec_nr = remote->push_refspec_nr;
|
||||||
refspec_nr = remote->push_refspec_nr;
|
} else if (!(flags & TRANSPORT_PUSH_MIRROR))
|
||||||
|
setup_default_push_refspecs();
|
||||||
}
|
}
|
||||||
errs = 0;
|
errs = 0;
|
||||||
for (i = 0; i < remote->url_nr; i++) {
|
for (i = 0; i < remote->url_nr; i++) {
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
|
|||||||
die("more than one --exclude-per-directory are given.");
|
die("more than one --exclude-per-directory are given.");
|
||||||
|
|
||||||
dir = xcalloc(1, sizeof(*opts.dir));
|
dir = xcalloc(1, sizeof(*opts.dir));
|
||||||
dir->show_ignored = 1;
|
dir->flags |= DIR_SHOW_IGNORED;
|
||||||
dir->exclude_per_dir = arg + 24;
|
dir->exclude_per_dir = arg + 24;
|
||||||
opts.dir = dir;
|
opts.dir = dir;
|
||||||
/* We do not need to nor want to do read-directory
|
/* We do not need to nor want to do read-directory
|
||||||
|
|||||||
569
builtin-remote.c
569
builtin-remote.c
@@ -12,12 +12,17 @@ static const char * const builtin_remote_usage[] = {
|
|||||||
"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 show [-n] <name>",
|
"git remote show [-n] <name>",
|
||||||
"git remote prune [-n | --dry-run] <name>",
|
"git remote prune [-n | --dry-run] <name>",
|
||||||
"git remote [-v | --verbose] update [group]",
|
"git remote [-v | --verbose] update [group]",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define GET_REF_STATES (1<<0)
|
||||||
|
#define GET_HEAD_NAMES (1<<1)
|
||||||
|
#define GET_PUSH_REF_STATES (1<<2)
|
||||||
|
|
||||||
static int verbose;
|
static int verbose;
|
||||||
|
|
||||||
static int show_all(void);
|
static int show_all(void);
|
||||||
@@ -143,8 +148,9 @@ static int add(int argc, const char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct branch_info {
|
struct branch_info {
|
||||||
char *remote;
|
char *remote_name;
|
||||||
struct string_list merge;
|
struct string_list merge;
|
||||||
|
int rebase;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct string_list branch_list;
|
static struct string_list branch_list;
|
||||||
@@ -161,10 +167,11 @@ static const char *abbrev_ref(const char *name, const char *prefix)
|
|||||||
static int config_read_branches(const char *key, const char *value, void *cb)
|
static int config_read_branches(const char *key, const char *value, void *cb)
|
||||||
{
|
{
|
||||||
if (!prefixcmp(key, "branch.")) {
|
if (!prefixcmp(key, "branch.")) {
|
||||||
|
const char *orig_key = key;
|
||||||
char *name;
|
char *name;
|
||||||
struct string_list_item *item;
|
struct string_list_item *item;
|
||||||
struct branch_info *info;
|
struct branch_info *info;
|
||||||
enum { REMOTE, MERGE } type;
|
enum { REMOTE, MERGE, REBASE } type;
|
||||||
|
|
||||||
key += 7;
|
key += 7;
|
||||||
if (!postfixcmp(key, ".remote")) {
|
if (!postfixcmp(key, ".remote")) {
|
||||||
@@ -173,6 +180,9 @@ static int config_read_branches(const char *key, const char *value, void *cb)
|
|||||||
} else if (!postfixcmp(key, ".merge")) {
|
} else if (!postfixcmp(key, ".merge")) {
|
||||||
name = xstrndup(key, strlen(key) - 6);
|
name = xstrndup(key, strlen(key) - 6);
|
||||||
type = MERGE;
|
type = MERGE;
|
||||||
|
} else if (!postfixcmp(key, ".rebase")) {
|
||||||
|
name = xstrndup(key, strlen(key) - 7);
|
||||||
|
type = REBASE;
|
||||||
} else
|
} else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -182,10 +192,10 @@ static int config_read_branches(const char *key, const char *value, void *cb)
|
|||||||
item->util = xcalloc(sizeof(struct branch_info), 1);
|
item->util = xcalloc(sizeof(struct branch_info), 1);
|
||||||
info = item->util;
|
info = item->util;
|
||||||
if (type == REMOTE) {
|
if (type == REMOTE) {
|
||||||
if (info->remote)
|
if (info->remote_name)
|
||||||
warning("more than one branch.%s", key);
|
warning("more than one %s", orig_key);
|
||||||
info->remote = xstrdup(value);
|
info->remote_name = xstrdup(value);
|
||||||
} else {
|
} else if (type == MERGE) {
|
||||||
char *space = strchr(value, ' ');
|
char *space = strchr(value, ' ');
|
||||||
value = abbrev_branch(value);
|
value = abbrev_branch(value);
|
||||||
while (space) {
|
while (space) {
|
||||||
@@ -196,7 +206,8 @@ static int config_read_branches(const char *key, const char *value, void *cb)
|
|||||||
space = strchr(value, ' ');
|
space = strchr(value, ' ');
|
||||||
}
|
}
|
||||||
string_list_append(xstrdup(value), &info->merge);
|
string_list_append(xstrdup(value), &info->merge);
|
||||||
}
|
} else
|
||||||
|
info->rebase = git_config_bool(orig_key, value);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -206,12 +217,12 @@ static void read_branches(void)
|
|||||||
if (branch_list.nr)
|
if (branch_list.nr)
|
||||||
return;
|
return;
|
||||||
git_config(config_read_branches, NULL);
|
git_config(config_read_branches, NULL);
|
||||||
sort_string_list(&branch_list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ref_states {
|
struct ref_states {
|
||||||
struct remote *remote;
|
struct remote *remote;
|
||||||
struct string_list new, stale, tracked;
|
struct string_list new, stale, tracked, heads, push;
|
||||||
|
int queried;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int handle_one_branch(const char *refname,
|
static int handle_one_branch(const char *refname,
|
||||||
@@ -227,10 +238,8 @@ static int handle_one_branch(const char *refname,
|
|||||||
const char *name = abbrev_branch(refspec.src);
|
const char *name = abbrev_branch(refspec.src);
|
||||||
/* symbolic refs pointing nowhere were handled already */
|
/* symbolic refs pointing nowhere were handled already */
|
||||||
if ((flags & REF_ISSYMREF) ||
|
if ((flags & REF_ISSYMREF) ||
|
||||||
unsorted_string_list_has_string(&states->tracked,
|
string_list_has_string(&states->tracked, name) ||
|
||||||
name) ||
|
string_list_has_string(&states->new, name))
|
||||||
unsorted_string_list_has_string(&states->new,
|
|
||||||
name))
|
|
||||||
return 0;
|
return 0;
|
||||||
item = string_list_append(name, &states->stale);
|
item = string_list_append(name, &states->stale);
|
||||||
item->util = xstrdup(refname);
|
item->util = xstrdup(refname);
|
||||||
@@ -238,39 +247,154 @@ static int handle_one_branch(const char *refname,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_ref_states(const struct ref *ref, struct ref_states *states)
|
static int get_ref_states(const struct ref *remote_refs, struct ref_states *states)
|
||||||
{
|
{
|
||||||
struct ref *fetch_map = NULL, **tail = &fetch_map;
|
struct ref *fetch_map = NULL, **tail = &fetch_map;
|
||||||
|
struct ref *ref;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < states->remote->fetch_refspec_nr; i++)
|
for (i = 0; i < states->remote->fetch_refspec_nr; i++)
|
||||||
if (get_fetch_map(ref, states->remote->fetch + i, &tail, 1))
|
if (get_fetch_map(remote_refs, states->remote->fetch + i, &tail, 1))
|
||||||
die("Could not get fetch map for refspec %s",
|
die("Could not get fetch map for refspec %s",
|
||||||
states->remote->fetch_refspec[i]);
|
states->remote->fetch_refspec[i]);
|
||||||
|
|
||||||
states->new.strdup_strings = states->tracked.strdup_strings = 1;
|
states->new.strdup_strings = states->tracked.strdup_strings = 1;
|
||||||
for (ref = fetch_map; ref; ref = ref->next) {
|
for (ref = fetch_map; ref; ref = ref->next) {
|
||||||
struct string_list *target = &states->tracked;
|
|
||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
void *util = NULL;
|
|
||||||
|
|
||||||
if (!ref->peer_ref || read_ref(ref->peer_ref->name, sha1))
|
if (!ref->peer_ref || read_ref(ref->peer_ref->name, sha1))
|
||||||
target = &states->new;
|
string_list_append(abbrev_branch(ref->name), &states->new);
|
||||||
else {
|
else
|
||||||
target = &states->tracked;
|
string_list_append(abbrev_branch(ref->name), &states->tracked);
|
||||||
if (hashcmp(sha1, ref->new_sha1))
|
|
||||||
util = &states;
|
|
||||||
}
|
|
||||||
string_list_append(abbrev_branch(ref->name), target)->util = util;
|
|
||||||
}
|
}
|
||||||
free_refs(fetch_map);
|
free_refs(fetch_map);
|
||||||
|
|
||||||
|
sort_string_list(&states->new);
|
||||||
|
sort_string_list(&states->tracked);
|
||||||
for_each_ref(handle_one_branch, states);
|
for_each_ref(handle_one_branch, states);
|
||||||
sort_string_list(&states->stale);
|
sort_string_list(&states->stale);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct push_info {
|
||||||
|
char *dest;
|
||||||
|
int forced;
|
||||||
|
enum {
|
||||||
|
PUSH_STATUS_CREATE = 0,
|
||||||
|
PUSH_STATUS_DELETE,
|
||||||
|
PUSH_STATUS_UPTODATE,
|
||||||
|
PUSH_STATUS_FASTFORWARD,
|
||||||
|
PUSH_STATUS_OUTOFDATE,
|
||||||
|
PUSH_STATUS_NOTQUERIED,
|
||||||
|
} status;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int get_push_ref_states(const struct ref *remote_refs,
|
||||||
|
struct ref_states *states)
|
||||||
|
{
|
||||||
|
struct remote *remote = states->remote;
|
||||||
|
struct ref *ref, *local_refs, *push_map, **push_tail;
|
||||||
|
if (remote->mirror)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
local_refs = get_local_heads();
|
||||||
|
ref = push_map = copy_ref_list(remote_refs);
|
||||||
|
while (ref->next)
|
||||||
|
ref = ref->next;
|
||||||
|
push_tail = &ref->next;
|
||||||
|
|
||||||
|
match_refs(local_refs, push_map, &push_tail, remote->push_refspec_nr,
|
||||||
|
remote->push_refspec, MATCH_REFS_NONE);
|
||||||
|
|
||||||
|
states->push.strdup_strings = 1;
|
||||||
|
for (ref = push_map; ref; ref = ref->next) {
|
||||||
|
struct string_list_item *item;
|
||||||
|
struct push_info *info;
|
||||||
|
|
||||||
|
if (!ref->peer_ref)
|
||||||
|
continue;
|
||||||
|
hashcpy(ref->new_sha1, ref->peer_ref->new_sha1);
|
||||||
|
|
||||||
|
item = string_list_append(abbrev_branch(ref->peer_ref->name),
|
||||||
|
&states->push);
|
||||||
|
item->util = xcalloc(sizeof(struct push_info), 1);
|
||||||
|
info = item->util;
|
||||||
|
info->forced = ref->force;
|
||||||
|
info->dest = xstrdup(abbrev_branch(ref->name));
|
||||||
|
|
||||||
|
if (is_null_sha1(ref->new_sha1)) {
|
||||||
|
info->status = PUSH_STATUS_DELETE;
|
||||||
|
} else if (!hashcmp(ref->old_sha1, ref->new_sha1))
|
||||||
|
info->status = PUSH_STATUS_UPTODATE;
|
||||||
|
else if (is_null_sha1(ref->old_sha1))
|
||||||
|
info->status = PUSH_STATUS_CREATE;
|
||||||
|
else if (has_sha1_file(ref->old_sha1) &&
|
||||||
|
ref_newer(ref->new_sha1, ref->old_sha1))
|
||||||
|
info->status = PUSH_STATUS_FASTFORWARD;
|
||||||
|
else
|
||||||
|
info->status = PUSH_STATUS_OUTOFDATE;
|
||||||
|
}
|
||||||
|
free_refs(local_refs);
|
||||||
|
free_refs(push_map);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_push_ref_states_noquery(struct ref_states *states)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct remote *remote = states->remote;
|
||||||
|
struct string_list_item *item;
|
||||||
|
struct push_info *info;
|
||||||
|
|
||||||
|
if (remote->mirror)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
states->push.strdup_strings = 1;
|
||||||
|
if (!remote->push_refspec_nr) {
|
||||||
|
item = string_list_append("(matching)", &states->push);
|
||||||
|
info = item->util = xcalloc(sizeof(struct push_info), 1);
|
||||||
|
info->status = PUSH_STATUS_NOTQUERIED;
|
||||||
|
info->dest = xstrdup(item->string);
|
||||||
|
}
|
||||||
|
for (i = 0; i < remote->push_refspec_nr; i++) {
|
||||||
|
struct refspec *spec = remote->push + i;
|
||||||
|
if (spec->matching)
|
||||||
|
item = string_list_append("(matching)", &states->push);
|
||||||
|
else if (strlen(spec->src))
|
||||||
|
item = string_list_append(spec->src, &states->push);
|
||||||
|
else
|
||||||
|
item = string_list_append("(delete)", &states->push);
|
||||||
|
|
||||||
|
info = item->util = xcalloc(sizeof(struct push_info), 1);
|
||||||
|
info->forced = spec->force;
|
||||||
|
info->status = PUSH_STATUS_NOTQUERIED;
|
||||||
|
info->dest = xstrdup(spec->dst ? spec->dst : item->string);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_head_names(const struct ref *remote_refs, struct ref_states *states)
|
||||||
|
{
|
||||||
|
struct ref *ref, *matches;
|
||||||
|
struct ref *fetch_map = NULL, **fetch_map_tail = &fetch_map;
|
||||||
|
struct refspec refspec;
|
||||||
|
|
||||||
|
refspec.force = 0;
|
||||||
|
refspec.pattern = 1;
|
||||||
|
refspec.src = refspec.dst = "refs/heads/*";
|
||||||
|
states->heads.strdup_strings = 1;
|
||||||
|
get_fetch_map(remote_refs, &refspec, &fetch_map_tail, 0);
|
||||||
|
matches = guess_remote_head(find_ref_by_name(remote_refs, "HEAD"),
|
||||||
|
fetch_map, 1);
|
||||||
|
for(ref = matches; ref; ref = ref->next)
|
||||||
|
string_list_append(abbrev_branch(ref->name), &states->heads);
|
||||||
|
|
||||||
|
free_refs(fetch_map);
|
||||||
|
free_refs(matches);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct known_remote {
|
struct known_remote {
|
||||||
struct known_remote *next;
|
struct known_remote *next;
|
||||||
struct remote *remote;
|
struct remote *remote;
|
||||||
@@ -466,7 +590,7 @@ static int mv(int argc, const char **argv)
|
|||||||
for (i = 0; i < branch_list.nr; i++) {
|
for (i = 0; i < branch_list.nr; i++) {
|
||||||
struct string_list_item *item = branch_list.items + i;
|
struct string_list_item *item = branch_list.items + i;
|
||||||
struct branch_info *info = item->util;
|
struct branch_info *info = item->util;
|
||||||
if (info->remote && !strcmp(info->remote, rename.old)) {
|
if (info->remote_name && !strcmp(info->remote_name, rename.old)) {
|
||||||
strbuf_reset(&buf);
|
strbuf_reset(&buf);
|
||||||
strbuf_addf(&buf, "branch.%s.remote", item->string);
|
strbuf_addf(&buf, "branch.%s.remote", item->string);
|
||||||
if (git_config_set(buf.buf, rename.new)) {
|
if (git_config_set(buf.buf, rename.new)) {
|
||||||
@@ -575,7 +699,7 @@ static int rm(int argc, const char **argv)
|
|||||||
for (i = 0; i < branch_list.nr; i++) {
|
for (i = 0; i < branch_list.nr; i++) {
|
||||||
struct string_list_item *item = branch_list.items + i;
|
struct string_list_item *item = branch_list.items + i;
|
||||||
struct branch_info *info = item->util;
|
struct branch_info *info = item->util;
|
||||||
if (info->remote && !strcmp(info->remote, remote->name)) {
|
if (info->remote_name && !strcmp(info->remote_name, remote->name)) {
|
||||||
const char *keys[] = { "remote", "merge", NULL }, **k;
|
const char *keys[] = { "remote", "merge", NULL }, **k;
|
||||||
for (k = keys; *k; k++) {
|
for (k = keys; *k; k++) {
|
||||||
strbuf_reset(&buf);
|
strbuf_reset(&buf);
|
||||||
@@ -617,18 +741,37 @@ static int rm(int argc, const char **argv)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show_list(const char *title, struct string_list *list,
|
void clear_push_info(void *util, const char *string)
|
||||||
const char *extra_arg)
|
|
||||||
{
|
{
|
||||||
int i;
|
struct push_info *info = util;
|
||||||
|
free(info->dest);
|
||||||
|
free(info);
|
||||||
|
}
|
||||||
|
|
||||||
if (!list->nr)
|
static void free_remote_ref_states(struct ref_states *states)
|
||||||
return;
|
{
|
||||||
|
string_list_clear(&states->new, 0);
|
||||||
|
string_list_clear(&states->stale, 0);
|
||||||
|
string_list_clear(&states->tracked, 0);
|
||||||
|
string_list_clear(&states->heads, 0);
|
||||||
|
string_list_clear_func(&states->push, clear_push_info);
|
||||||
|
}
|
||||||
|
|
||||||
printf(title, list->nr > 1 ? "es" : "", extra_arg);
|
static int append_ref_to_tracked_list(const char *refname,
|
||||||
printf("\n");
|
const unsigned char *sha1, int flags, void *cb_data)
|
||||||
for (i = 0; i < list->nr; i++)
|
{
|
||||||
printf(" %s\n", list->items[i].string);
|
struct ref_states *states = cb_data;
|
||||||
|
struct refspec refspec;
|
||||||
|
|
||||||
|
if (flags & REF_ISSYMREF)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
memset(&refspec, 0, sizeof(refspec));
|
||||||
|
refspec.dst = (char *)refname;
|
||||||
|
if (!remote_find_tracking(states->remote, &refspec))
|
||||||
|
string_list_append(abbrev_branch(refspec.src), &states->tracked);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_remote_ref_states(const char *name,
|
static int get_remote_ref_states(const char *name,
|
||||||
@@ -636,7 +779,7 @@ static int get_remote_ref_states(const char *name,
|
|||||||
int query)
|
int query)
|
||||||
{
|
{
|
||||||
struct transport *transport;
|
struct transport *transport;
|
||||||
const struct ref *ref;
|
const struct ref *remote_refs;
|
||||||
|
|
||||||
states->remote = remote_get(name);
|
states->remote = remote_get(name);
|
||||||
if (!states->remote)
|
if (!states->remote)
|
||||||
@@ -647,105 +790,336 @@ static int get_remote_ref_states(const char *name,
|
|||||||
if (query) {
|
if (query) {
|
||||||
transport = transport_get(NULL, states->remote->url_nr > 0 ?
|
transport = transport_get(NULL, states->remote->url_nr > 0 ?
|
||||||
states->remote->url[0] : NULL);
|
states->remote->url[0] : NULL);
|
||||||
ref = transport_get_remote_refs(transport);
|
remote_refs = transport_get_remote_refs(transport);
|
||||||
transport_disconnect(transport);
|
transport_disconnect(transport);
|
||||||
|
|
||||||
get_ref_states(ref, states);
|
states->queried = 1;
|
||||||
|
if (query & GET_REF_STATES)
|
||||||
|
get_ref_states(remote_refs, states);
|
||||||
|
if (query & GET_HEAD_NAMES)
|
||||||
|
get_head_names(remote_refs, states);
|
||||||
|
if (query & GET_PUSH_REF_STATES)
|
||||||
|
get_push_ref_states(remote_refs, states);
|
||||||
|
} else {
|
||||||
|
for_each_ref(append_ref_to_tracked_list, states);
|
||||||
|
sort_string_list(&states->tracked);
|
||||||
|
get_push_ref_states_noquery(states);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int append_ref_to_tracked_list(const char *refname,
|
struct show_info {
|
||||||
const unsigned char *sha1, int flags, void *cb_data)
|
struct string_list *list;
|
||||||
|
struct ref_states *states;
|
||||||
|
int width, width2;
|
||||||
|
int any_rebase;
|
||||||
|
};
|
||||||
|
|
||||||
|
int add_remote_to_show_info(struct string_list_item *item, void *cb_data)
|
||||||
{
|
{
|
||||||
struct ref_states *states = cb_data;
|
struct show_info *info = cb_data;
|
||||||
struct refspec refspec;
|
int n = strlen(item->string);
|
||||||
|
if (n > info->width)
|
||||||
|
info->width = n;
|
||||||
|
string_list_insert(item->string, info->list);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&refspec, 0, sizeof(refspec));
|
int show_remote_info_item(struct string_list_item *item, void *cb_data)
|
||||||
refspec.dst = (char *)refname;
|
{
|
||||||
if (!remote_find_tracking(states->remote, &refspec))
|
struct show_info *info = cb_data;
|
||||||
string_list_append(abbrev_branch(refspec.src), &states->tracked);
|
struct ref_states *states = info->states;
|
||||||
|
const char *name = item->string;
|
||||||
|
|
||||||
|
if (states->queried) {
|
||||||
|
const char *fmt = "%s";
|
||||||
|
const char *arg = "";
|
||||||
|
if (string_list_has_string(&states->new, name)) {
|
||||||
|
fmt = " new (next fetch will store in remotes/%s)";
|
||||||
|
arg = states->remote->name;
|
||||||
|
} else if (string_list_has_string(&states->tracked, name))
|
||||||
|
arg = " tracked";
|
||||||
|
else if (string_list_has_string(&states->stale, name))
|
||||||
|
arg = " stale (use 'git remote prune' to remove)";
|
||||||
|
else
|
||||||
|
arg = " ???";
|
||||||
|
printf(" %-*s", info->width, name);
|
||||||
|
printf(fmt, arg);
|
||||||
|
printf("\n");
|
||||||
|
} else
|
||||||
|
printf(" %s\n", name);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int add_local_to_show_info(struct string_list_item *branch_item, void *cb_data)
|
||||||
|
{
|
||||||
|
struct show_info *show_info = cb_data;
|
||||||
|
struct ref_states *states = show_info->states;
|
||||||
|
struct branch_info *branch_info = branch_item->util;
|
||||||
|
struct string_list_item *item;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if (!branch_info->merge.nr || !branch_info->remote_name ||
|
||||||
|
strcmp(states->remote->name, branch_info->remote_name))
|
||||||
|
return 0;
|
||||||
|
if ((n = strlen(branch_item->string)) > show_info->width)
|
||||||
|
show_info->width = n;
|
||||||
|
if (branch_info->rebase)
|
||||||
|
show_info->any_rebase = 1;
|
||||||
|
|
||||||
|
item = string_list_insert(branch_item->string, show_info->list);
|
||||||
|
item->util = branch_info;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int show_local_info_item(struct string_list_item *item, void *cb_data)
|
||||||
|
{
|
||||||
|
struct show_info *show_info = cb_data;
|
||||||
|
struct branch_info *branch_info = item->util;
|
||||||
|
struct string_list *merge = &branch_info->merge;
|
||||||
|
const char *also;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (branch_info->rebase && branch_info->merge.nr > 1) {
|
||||||
|
error("invalid branch.%s.merge; cannot rebase onto > 1 branch",
|
||||||
|
item->string);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(" %-*s ", show_info->width, item->string);
|
||||||
|
if (branch_info->rebase) {
|
||||||
|
printf("rebases onto remote %s\n", merge->items[0].string);
|
||||||
|
return 0;
|
||||||
|
} else if (show_info->any_rebase) {
|
||||||
|
printf(" merges with remote %s\n", merge->items[0].string);
|
||||||
|
also = " and with remote";
|
||||||
|
} else {
|
||||||
|
printf("merges with remote %s\n", merge->items[0].string);
|
||||||
|
also = " and with remote";
|
||||||
|
}
|
||||||
|
for (i = 1; i < merge->nr; i++)
|
||||||
|
printf(" %-*s %s %s\n", show_info->width, "", also,
|
||||||
|
merge->items[i].string);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int add_push_to_show_info(struct string_list_item *push_item, void *cb_data)
|
||||||
|
{
|
||||||
|
struct show_info *show_info = cb_data;
|
||||||
|
struct push_info *push_info = push_item->util;
|
||||||
|
struct string_list_item *item;
|
||||||
|
int n;
|
||||||
|
if ((n = strlen(push_item->string)) > show_info->width)
|
||||||
|
show_info->width = n;
|
||||||
|
if ((n = strlen(push_info->dest)) > show_info->width2)
|
||||||
|
show_info->width2 = n;
|
||||||
|
item = string_list_append(push_item->string, show_info->list);
|
||||||
|
item->util = push_item->util;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sorting comparison for a string list that has push_info
|
||||||
|
* structs in its util field
|
||||||
|
*/
|
||||||
|
static int cmp_string_with_push(const void *va, const void *vb)
|
||||||
|
{
|
||||||
|
const struct string_list_item *a = va;
|
||||||
|
const struct string_list_item *b = vb;
|
||||||
|
const struct push_info *a_push = a->util;
|
||||||
|
const struct push_info *b_push = b->util;
|
||||||
|
int cmp = strcmp(a->string, b->string);
|
||||||
|
return cmp ? cmp : strcmp(a_push->dest, b_push->dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
int show_push_info_item(struct string_list_item *item, void *cb_data)
|
||||||
|
{
|
||||||
|
struct show_info *show_info = cb_data;
|
||||||
|
struct push_info *push_info = item->util;
|
||||||
|
char *src = item->string, *status = NULL;
|
||||||
|
|
||||||
|
switch (push_info->status) {
|
||||||
|
case PUSH_STATUS_CREATE:
|
||||||
|
status = "create";
|
||||||
|
break;
|
||||||
|
case PUSH_STATUS_DELETE:
|
||||||
|
status = "delete";
|
||||||
|
src = "(none)";
|
||||||
|
break;
|
||||||
|
case PUSH_STATUS_UPTODATE:
|
||||||
|
status = "up to date";
|
||||||
|
break;
|
||||||
|
case PUSH_STATUS_FASTFORWARD:
|
||||||
|
status = "fast forwardable";
|
||||||
|
break;
|
||||||
|
case PUSH_STATUS_OUTOFDATE:
|
||||||
|
status = "local out of date";
|
||||||
|
break;
|
||||||
|
case PUSH_STATUS_NOTQUERIED:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (status)
|
||||||
|
printf(" %-*s %s to %-*s (%s)\n", show_info->width, src,
|
||||||
|
push_info->forced ? "forces" : "pushes",
|
||||||
|
show_info->width2, push_info->dest, status);
|
||||||
|
else
|
||||||
|
printf(" %-*s %s to %s\n", show_info->width, src,
|
||||||
|
push_info->forced ? "forces" : "pushes",
|
||||||
|
push_info->dest);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int show(int argc, const char **argv)
|
static int show(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
int no_query = 0, result = 0;
|
int no_query = 0, result = 0, query_flag = 0;
|
||||||
struct option options[] = {
|
struct option options[] = {
|
||||||
OPT_GROUP("show specific options"),
|
OPT_GROUP("show specific options"),
|
||||||
OPT_BOOLEAN('n', NULL, &no_query, "do not query remotes"),
|
OPT_BOOLEAN('n', NULL, &no_query, "do not query remotes"),
|
||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
struct ref_states states;
|
struct ref_states states;
|
||||||
|
struct string_list info_list = { NULL, 0, 0, 0 };
|
||||||
|
struct show_info info;
|
||||||
|
|
||||||
argc = parse_options(argc, argv, options, builtin_remote_usage, 0);
|
argc = parse_options(argc, argv, options, builtin_remote_usage, 0);
|
||||||
|
|
||||||
if (argc < 1)
|
if (argc < 1)
|
||||||
return show_all();
|
return show_all();
|
||||||
|
|
||||||
|
if (!no_query)
|
||||||
|
query_flag = (GET_REF_STATES | GET_HEAD_NAMES | GET_PUSH_REF_STATES);
|
||||||
|
|
||||||
memset(&states, 0, sizeof(states));
|
memset(&states, 0, sizeof(states));
|
||||||
|
memset(&info, 0, sizeof(info));
|
||||||
|
info.states = &states;
|
||||||
|
info.list = &info_list;
|
||||||
for (; argc; argc--, argv++) {
|
for (; argc; argc--, argv++) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
get_remote_ref_states(*argv, &states, !no_query);
|
get_remote_ref_states(*argv, &states, query_flag);
|
||||||
|
|
||||||
printf("* remote %s\n URL: %s\n", *argv,
|
printf("* remote %s\n URL: %s\n", *argv,
|
||||||
states.remote->url_nr > 0 ?
|
states.remote->url_nr > 0 ?
|
||||||
states.remote->url[0] : "(no URL)");
|
states.remote->url[0] : "(no URL)");
|
||||||
|
|
||||||
for (i = 0; i < branch_list.nr; i++) {
|
|
||||||
struct string_list_item *branch = branch_list.items + i;
|
|
||||||
struct branch_info *info = branch->util;
|
|
||||||
int j;
|
|
||||||
|
|
||||||
if (!info->merge.nr || strcmp(*argv, info->remote))
|
|
||||||
continue;
|
|
||||||
printf(" Remote branch%s merged with 'git pull' "
|
|
||||||
"while on branch %s\n ",
|
|
||||||
info->merge.nr > 1 ? "es" : "",
|
|
||||||
branch->string);
|
|
||||||
for (j = 0; j < info->merge.nr; j++)
|
|
||||||
printf(" %s", info->merge.items[j].string);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!no_query) {
|
|
||||||
show_list(" New remote branch%s (next fetch "
|
|
||||||
"will store in remotes/%s)",
|
|
||||||
&states.new, states.remote->name);
|
|
||||||
show_list(" Stale tracking branch%s (use 'git remote "
|
|
||||||
"prune')", &states.stale, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (no_query)
|
if (no_query)
|
||||||
for_each_ref(append_ref_to_tracked_list, &states);
|
printf(" HEAD branch: (not queried)\n");
|
||||||
show_list(" Tracked remote branch%s", &states.tracked, "");
|
else if (!states.heads.nr)
|
||||||
|
printf(" HEAD branch: (unknown)\n");
|
||||||
if (states.remote->push_refspec_nr) {
|
else if (states.heads.nr == 1)
|
||||||
printf(" Local branch%s pushed with 'git push'\n",
|
printf(" HEAD branch: %s\n", states.heads.items[0].string);
|
||||||
states.remote->push_refspec_nr > 1 ?
|
else {
|
||||||
"es" : "");
|
printf(" HEAD branch (remote HEAD is ambiguous,"
|
||||||
for (i = 0; i < states.remote->push_refspec_nr; i++) {
|
" may be one of the following):\n");
|
||||||
struct refspec *spec = states.remote->push + i;
|
for (i = 0; i < states.heads.nr; i++)
|
||||||
printf(" %s%s%s%s\n",
|
printf(" %s\n", states.heads.items[i].string);
|
||||||
spec->force ? "+" : "",
|
|
||||||
abbrev_branch(spec->src),
|
|
||||||
spec->dst ? ":" : "",
|
|
||||||
spec->dst ? abbrev_branch(spec->dst) : "");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NEEDSWORK: free remote */
|
/* remote branch info */
|
||||||
string_list_clear(&states.new, 0);
|
info.width = 0;
|
||||||
string_list_clear(&states.stale, 0);
|
for_each_string_list(add_remote_to_show_info, &states.new, &info);
|
||||||
string_list_clear(&states.tracked, 0);
|
for_each_string_list(add_remote_to_show_info, &states.tracked, &info);
|
||||||
|
for_each_string_list(add_remote_to_show_info, &states.stale, &info);
|
||||||
|
if (info.list->nr)
|
||||||
|
printf(" Remote branch%s:%s\n",
|
||||||
|
info.list->nr > 1 ? "es" : "",
|
||||||
|
no_query ? " (status not queried)" : "");
|
||||||
|
for_each_string_list(show_remote_info_item, info.list, &info);
|
||||||
|
string_list_clear(info.list, 0);
|
||||||
|
|
||||||
|
/* git pull info */
|
||||||
|
info.width = 0;
|
||||||
|
info.any_rebase = 0;
|
||||||
|
for_each_string_list(add_local_to_show_info, &branch_list, &info);
|
||||||
|
if (info.list->nr)
|
||||||
|
printf(" Local branch%s configured for 'git pull':\n",
|
||||||
|
info.list->nr > 1 ? "es" : "");
|
||||||
|
for_each_string_list(show_local_info_item, info.list, &info);
|
||||||
|
string_list_clear(info.list, 0);
|
||||||
|
|
||||||
|
/* git push info */
|
||||||
|
if (states.remote->mirror)
|
||||||
|
printf(" Local refs will be mirrored by 'git push'\n");
|
||||||
|
|
||||||
|
info.width = info.width2 = 0;
|
||||||
|
for_each_string_list(add_push_to_show_info, &states.push, &info);
|
||||||
|
qsort(info.list->items, info.list->nr,
|
||||||
|
sizeof(*info.list->items), cmp_string_with_push);
|
||||||
|
if (info.list->nr)
|
||||||
|
printf(" Local ref%s configured for 'git push'%s:\n",
|
||||||
|
info.list->nr > 1 ? "s" : "",
|
||||||
|
no_query ? " (status not queried)" : "");
|
||||||
|
for_each_string_list(show_push_info_item, info.list, &info);
|
||||||
|
string_list_clear(info.list, 0);
|
||||||
|
|
||||||
|
free_remote_ref_states(&states);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_head(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
int i, opt_a = 0, opt_d = 0, result = 0;
|
||||||
|
struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT;
|
||||||
|
char *head_name = NULL;
|
||||||
|
|
||||||
|
struct option options[] = {
|
||||||
|
OPT_GROUP("set-head specific options"),
|
||||||
|
OPT_BOOLEAN('a', "auto", &opt_a,
|
||||||
|
"set refs/remotes/<name>/HEAD according to remote"),
|
||||||
|
OPT_BOOLEAN('d', "delete", &opt_d,
|
||||||
|
"delete refs/remotes/<name>/HEAD"),
|
||||||
|
OPT_END()
|
||||||
|
};
|
||||||
|
argc = parse_options(argc, argv, options, builtin_remote_usage, 0);
|
||||||
|
if (argc)
|
||||||
|
strbuf_addf(&buf, "refs/remotes/%s/HEAD", argv[0]);
|
||||||
|
|
||||||
|
if (!opt_a && !opt_d && argc == 2) {
|
||||||
|
head_name = xstrdup(argv[1]);
|
||||||
|
} else if (opt_a && !opt_d && argc == 1) {
|
||||||
|
struct ref_states states;
|
||||||
|
memset(&states, 0, sizeof(states));
|
||||||
|
get_remote_ref_states(argv[0], &states, GET_HEAD_NAMES);
|
||||||
|
if (!states.heads.nr)
|
||||||
|
result |= error("Cannot determine remote HEAD");
|
||||||
|
else if (states.heads.nr > 1) {
|
||||||
|
result |= error("Multiple remote HEAD branches. "
|
||||||
|
"Please choose one explicitly with:");
|
||||||
|
for (i = 0; i < states.heads.nr; i++)
|
||||||
|
fprintf(stderr, " git remote set-head %s %s\n",
|
||||||
|
argv[0], states.heads.items[i].string);
|
||||||
|
} else
|
||||||
|
head_name = xstrdup(states.heads.items[0].string);
|
||||||
|
free_remote_ref_states(&states);
|
||||||
|
} else if (opt_d && !opt_a && argc == 1) {
|
||||||
|
if (delete_ref(buf.buf, NULL, REF_NODEREF))
|
||||||
|
result |= error("Could not delete %s", buf.buf);
|
||||||
|
} else
|
||||||
|
usage_with_options(builtin_remote_usage, options);
|
||||||
|
|
||||||
|
if (head_name) {
|
||||||
|
unsigned char sha1[20];
|
||||||
|
strbuf_addf(&buf2, "refs/remotes/%s/%s", argv[0], head_name);
|
||||||
|
/* make sure it's valid */
|
||||||
|
if (!resolve_ref(buf2.buf, sha1, 1, NULL))
|
||||||
|
result |= error("Not a valid ref: %s", buf2.buf);
|
||||||
|
else if (create_symref(buf.buf, buf2.buf, "remote set-head"))
|
||||||
|
result |= error("Could not setup %s", buf.buf);
|
||||||
|
if (opt_a)
|
||||||
|
printf("%s/HEAD set to %s\n", argv[0], head_name);
|
||||||
|
free(head_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
strbuf_release(&buf);
|
||||||
|
strbuf_release(&buf2);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static int prune(int argc, const char **argv)
|
static int prune(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
int dry_run = 0, result = 0;
|
int dry_run = 0, result = 0;
|
||||||
@@ -770,7 +1144,7 @@ static int prune(int argc, const char **argv)
|
|||||||
for (; argc; argc--, argv++) {
|
for (; argc; argc--, argv++) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
get_remote_ref_states(*argv, &states, 1);
|
get_remote_ref_states(*argv, &states, GET_REF_STATES);
|
||||||
|
|
||||||
if (states.stale.nr) {
|
if (states.stale.nr) {
|
||||||
printf("Pruning %s\n", *argv);
|
printf("Pruning %s\n", *argv);
|
||||||
@@ -791,10 +1165,7 @@ static int prune(int argc, const char **argv)
|
|||||||
warn_dangling_symref(dangling_msg, refname);
|
warn_dangling_symref(dangling_msg, refname);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NEEDSWORK: free remote */
|
free_remote_ref_states(&states);
|
||||||
string_list_clear(&states.new, 0);
|
|
||||||
string_list_clear(&states.stale, 0);
|
|
||||||
string_list_clear(&states.tracked, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -919,6 +1290,8 @@ int cmd_remote(int argc, const char **argv, const char *prefix)
|
|||||||
result = mv(argc, argv);
|
result = mv(argc, argv);
|
||||||
else if (!strcmp(argv[0], "rm"))
|
else if (!strcmp(argv[0], "rm"))
|
||||||
result = rm(argc, argv);
|
result = rm(argc, argv);
|
||||||
|
else if (!strcmp(argv[0], "set-head"))
|
||||||
|
result = set_head(argc, argv);
|
||||||
else if (!strcmp(argv[0], "show"))
|
else if (!strcmp(argv[0], "show"))
|
||||||
result = show(argc, argv);
|
result = show(argc, argv);
|
||||||
else if (!strcmp(argv[0], "prune"))
|
else if (!strcmp(argv[0], "prune"))
|
||||||
|
|||||||
@@ -59,8 +59,7 @@ static int check_local_mod(unsigned char *head, int index_only)
|
|||||||
|
|
||||||
if (lstat(ce->name, &st) < 0) {
|
if (lstat(ce->name, &st) < 0) {
|
||||||
if (errno != ENOENT)
|
if (errno != ENOENT)
|
||||||
fprintf(stderr, "warning: '%s': %s",
|
warning("'%s': %s", ce->name, strerror(errno));
|
||||||
ce->name, strerror(errno));
|
|
||||||
/* It already vanished from the working tree */
|
/* It already vanished from the working tree */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "tag.h"
|
|
||||||
#include "refs.h"
|
#include "refs.h"
|
||||||
#include "pkt-line.h"
|
#include "pkt-line.h"
|
||||||
#include "run-command.h"
|
#include "run-command.h"
|
||||||
@@ -11,9 +10,7 @@ static const char send_pack_usage[] =
|
|||||||
"git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n"
|
"git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n"
|
||||||
" --all and explicit <ref> specification are mutually exclusive.";
|
" --all and explicit <ref> specification are mutually exclusive.";
|
||||||
|
|
||||||
static struct send_pack_args args = {
|
static struct send_pack_args args;
|
||||||
/* .receivepack = */ "git-receive-pack",
|
|
||||||
};
|
|
||||||
|
|
||||||
static int feed_object(const unsigned char *sha1, int fd, int negative)
|
static int feed_object(const unsigned char *sha1, int fd, int negative)
|
||||||
{
|
{
|
||||||
@@ -32,7 +29,7 @@ static int feed_object(const unsigned char *sha1, int fd, int negative)
|
|||||||
/*
|
/*
|
||||||
* Make a pack stream and spit it out into file descriptor fd
|
* Make a pack stream and spit it out into file descriptor fd
|
||||||
*/
|
*/
|
||||||
static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *extra)
|
static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *extra, struct send_pack_args *args)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* The child becomes pack-objects --revs; we feed
|
* The child becomes pack-objects --revs; we feed
|
||||||
@@ -50,7 +47,7 @@ static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *ext
|
|||||||
struct child_process po;
|
struct child_process po;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (args.use_thin_pack)
|
if (args->use_thin_pack)
|
||||||
argv[4] = "--thin";
|
argv[4] = "--thin";
|
||||||
memset(&po, 0, sizeof(po));
|
memset(&po, 0, sizeof(po));
|
||||||
po.argv = argv;
|
po.argv = argv;
|
||||||
@@ -84,82 +81,6 @@ static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *ext
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unmark_and_free(struct commit_list *list, unsigned int mark)
|
|
||||||
{
|
|
||||||
while (list) {
|
|
||||||
struct commit_list *temp = list;
|
|
||||||
temp->item->object.flags &= ~mark;
|
|
||||||
list = temp->next;
|
|
||||||
free(temp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ref_newer(const unsigned char *new_sha1,
|
|
||||||
const unsigned char *old_sha1)
|
|
||||||
{
|
|
||||||
struct object *o;
|
|
||||||
struct commit *old, *new;
|
|
||||||
struct commit_list *list, *used;
|
|
||||||
int found = 0;
|
|
||||||
|
|
||||||
/* Both new and old must be commit-ish and new is descendant of
|
|
||||||
* old. Otherwise we require --force.
|
|
||||||
*/
|
|
||||||
o = deref_tag(parse_object(old_sha1), NULL, 0);
|
|
||||||
if (!o || o->type != OBJ_COMMIT)
|
|
||||||
return 0;
|
|
||||||
old = (struct commit *) o;
|
|
||||||
|
|
||||||
o = deref_tag(parse_object(new_sha1), NULL, 0);
|
|
||||||
if (!o || o->type != OBJ_COMMIT)
|
|
||||||
return 0;
|
|
||||||
new = (struct commit *) o;
|
|
||||||
|
|
||||||
if (parse_commit(new) < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
used = list = NULL;
|
|
||||||
commit_list_insert(new, &list);
|
|
||||||
while (list) {
|
|
||||||
new = pop_most_recent_commit(&list, 1);
|
|
||||||
commit_list_insert(new, &used);
|
|
||||||
if (new == old) {
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unmark_and_free(list, 1);
|
|
||||||
unmark_and_free(used, 1);
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ref *local_refs, **local_tail;
|
|
||||||
static struct ref *remote_refs, **remote_tail;
|
|
||||||
|
|
||||||
static int one_local_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
|
|
||||||
{
|
|
||||||
struct ref *ref;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
/* we already know it starts with refs/ to get here */
|
|
||||||
if (check_ref_format(refname + 5))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
len = strlen(refname) + 1;
|
|
||||||
ref = xcalloc(1, sizeof(*ref) + len);
|
|
||||||
hashcpy(ref->new_sha1, sha1);
|
|
||||||
memcpy(ref->name, refname, len);
|
|
||||||
*local_tail = ref;
|
|
||||||
local_tail = &ref->next;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void get_local_heads(void)
|
|
||||||
{
|
|
||||||
local_tail = &local_refs;
|
|
||||||
for_each_ref(one_local_ref, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int receive_status(int in, struct ref *refs)
|
static int receive_status(int in, struct ref *refs)
|
||||||
{
|
{
|
||||||
struct ref *hint;
|
struct ref *hint;
|
||||||
@@ -247,16 +168,6 @@ static void update_tracking_ref(struct remote *remote, struct ref *ref)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *prettify_ref(const struct ref *ref)
|
|
||||||
{
|
|
||||||
const char *name = ref->name;
|
|
||||||
return name + (
|
|
||||||
!prefixcmp(name, "refs/heads/") ? 11 :
|
|
||||||
!prefixcmp(name, "refs/tags/") ? 10 :
|
|
||||||
!prefixcmp(name, "refs/remotes/") ? 13 :
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SUMMARY_WIDTH (2 * DEFAULT_ABBREV + 3)
|
#define SUMMARY_WIDTH (2 * DEFAULT_ABBREV + 3)
|
||||||
|
|
||||||
static void print_ref_status(char flag, const char *summary, struct ref *to, struct ref *from, const char *msg)
|
static void print_ref_status(char flag, const char *summary, struct ref *to, struct ref *from, const char *msg)
|
||||||
@@ -385,27 +296,19 @@ static int refs_pushed(struct ref *ref)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_send_pack(int in, int out, struct remote *remote, const char *dest, int nr_refspec, const char **refspec)
|
int send_pack(struct send_pack_args *args,
|
||||||
|
int fd[], struct child_process *conn,
|
||||||
|
struct ref *remote_refs,
|
||||||
|
struct extra_have_objects *extra_have)
|
||||||
{
|
{
|
||||||
|
int in = fd[0];
|
||||||
|
int out = fd[1];
|
||||||
struct ref *ref;
|
struct ref *ref;
|
||||||
int new_refs;
|
int new_refs;
|
||||||
int ask_for_status_report = 0;
|
int ask_for_status_report = 0;
|
||||||
int allow_deleting_refs = 0;
|
int allow_deleting_refs = 0;
|
||||||
int expect_status_report = 0;
|
int expect_status_report = 0;
|
||||||
int flags = MATCH_REFS_NONE;
|
|
||||||
int ret;
|
int ret;
|
||||||
struct extra_have_objects extra_have;
|
|
||||||
|
|
||||||
memset(&extra_have, 0, sizeof(extra_have));
|
|
||||||
if (args.send_all)
|
|
||||||
flags |= MATCH_REFS_ALL;
|
|
||||||
if (args.send_mirror)
|
|
||||||
flags |= MATCH_REFS_MIRROR;
|
|
||||||
|
|
||||||
/* No funny business with the matcher */
|
|
||||||
remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, REF_NORMAL,
|
|
||||||
&extra_have);
|
|
||||||
get_local_heads();
|
|
||||||
|
|
||||||
/* Does the other end support the reporting? */
|
/* Does the other end support the reporting? */
|
||||||
if (server_supports("report-status"))
|
if (server_supports("report-status"))
|
||||||
@@ -413,19 +316,9 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest
|
|||||||
if (server_supports("delete-refs"))
|
if (server_supports("delete-refs"))
|
||||||
allow_deleting_refs = 1;
|
allow_deleting_refs = 1;
|
||||||
|
|
||||||
/* match them up */
|
|
||||||
if (!remote_tail)
|
|
||||||
remote_tail = &remote_refs;
|
|
||||||
if (match_refs(local_refs, remote_refs, &remote_tail,
|
|
||||||
nr_refspec, refspec, flags)) {
|
|
||||||
close(out);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!remote_refs) {
|
if (!remote_refs) {
|
||||||
fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
|
fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
|
||||||
"Perhaps you should specify a branch such as 'master'.\n");
|
"Perhaps you should specify a branch such as 'master'.\n");
|
||||||
close(out);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,7 +330,7 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest
|
|||||||
|
|
||||||
if (ref->peer_ref)
|
if (ref->peer_ref)
|
||||||
hashcpy(ref->new_sha1, ref->peer_ref->new_sha1);
|
hashcpy(ref->new_sha1, ref->peer_ref->new_sha1);
|
||||||
else if (!args.send_mirror)
|
else if (!args->send_mirror)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ref->deletion = is_null_sha1(ref->new_sha1);
|
ref->deletion = is_null_sha1(ref->new_sha1);
|
||||||
@@ -476,7 +369,7 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest
|
|||||||
(!has_sha1_file(ref->old_sha1)
|
(!has_sha1_file(ref->old_sha1)
|
||||||
|| !ref_newer(ref->new_sha1, ref->old_sha1));
|
|| !ref_newer(ref->new_sha1, ref->old_sha1));
|
||||||
|
|
||||||
if (ref->nonfastforward && !ref->force && !args.force_update) {
|
if (ref->nonfastforward && !ref->force && !args->force_update) {
|
||||||
ref->status = REF_STATUS_REJECT_NONFASTFORWARD;
|
ref->status = REF_STATUS_REJECT_NONFASTFORWARD;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -484,7 +377,7 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest
|
|||||||
if (!ref->deletion)
|
if (!ref->deletion)
|
||||||
new_refs++;
|
new_refs++;
|
||||||
|
|
||||||
if (!args.dry_run) {
|
if (!args->dry_run) {
|
||||||
char *old_hex = sha1_to_hex(ref->old_sha1);
|
char *old_hex = sha1_to_hex(ref->old_sha1);
|
||||||
char *new_hex = sha1_to_hex(ref->new_sha1);
|
char *new_hex = sha1_to_hex(ref->new_sha1);
|
||||||
|
|
||||||
@@ -505,27 +398,19 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest
|
|||||||
}
|
}
|
||||||
|
|
||||||
packet_flush(out);
|
packet_flush(out);
|
||||||
if (new_refs && !args.dry_run) {
|
if (new_refs && !args->dry_run) {
|
||||||
if (pack_objects(out, remote_refs, &extra_have) < 0)
|
if (pack_objects(out, remote_refs, extra_have, args) < 0) {
|
||||||
|
for (ref = remote_refs; ref; ref = ref->next)
|
||||||
|
ref->status = REF_STATUS_NONE;
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
close(out);
|
|
||||||
|
|
||||||
if (expect_status_report)
|
if (expect_status_report)
|
||||||
ret = receive_status(in, remote_refs);
|
ret = receive_status(in, remote_refs);
|
||||||
else
|
else
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
print_push_status(dest, remote_refs);
|
|
||||||
|
|
||||||
if (!args.dry_run && remote) {
|
|
||||||
for (ref = remote_refs; ref; ref = ref->next)
|
|
||||||
update_tracking_ref(remote, ref);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!refs_pushed(remote_refs))
|
|
||||||
fprintf(stderr, "Everything up-to-date\n");
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
for (ref = remote_refs; ref; ref = ref->next) {
|
for (ref = remote_refs; ref; ref = ref->next) {
|
||||||
@@ -574,11 +459,19 @@ static void verify_remote_names(int nr_heads, const char **heads)
|
|||||||
|
|
||||||
int cmd_send_pack(int argc, const char **argv, const char *prefix)
|
int cmd_send_pack(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int i, nr_heads = 0;
|
int i, nr_refspecs = 0;
|
||||||
const char **heads = NULL;
|
const char **refspecs = NULL;
|
||||||
const char *remote_name = NULL;
|
const char *remote_name = NULL;
|
||||||
struct remote *remote = NULL;
|
struct remote *remote = NULL;
|
||||||
const char *dest = NULL;
|
const char *dest = NULL;
|
||||||
|
int fd[2];
|
||||||
|
struct child_process *conn;
|
||||||
|
struct extra_have_objects extra_have;
|
||||||
|
struct ref *remote_refs, **remote_tail, *local_refs;
|
||||||
|
int ret;
|
||||||
|
int send_all = 0;
|
||||||
|
const char *receivepack = "git-receive-pack";
|
||||||
|
int flags;
|
||||||
|
|
||||||
argv++;
|
argv++;
|
||||||
for (i = 1; i < argc; i++, argv++) {
|
for (i = 1; i < argc; i++, argv++) {
|
||||||
@@ -586,11 +479,11 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
|
|||||||
|
|
||||||
if (*arg == '-') {
|
if (*arg == '-') {
|
||||||
if (!prefixcmp(arg, "--receive-pack=")) {
|
if (!prefixcmp(arg, "--receive-pack=")) {
|
||||||
args.receivepack = arg + 15;
|
receivepack = arg + 15;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!prefixcmp(arg, "--exec=")) {
|
if (!prefixcmp(arg, "--exec=")) {
|
||||||
args.receivepack = arg + 7;
|
receivepack = arg + 7;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!prefixcmp(arg, "--remote=")) {
|
if (!prefixcmp(arg, "--remote=")) {
|
||||||
@@ -598,7 +491,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!strcmp(arg, "--all")) {
|
if (!strcmp(arg, "--all")) {
|
||||||
args.send_all = 1;
|
send_all = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!strcmp(arg, "--dry-run")) {
|
if (!strcmp(arg, "--dry-run")) {
|
||||||
@@ -627,8 +520,8 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
|
|||||||
dest = arg;
|
dest = arg;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
heads = (const char **) argv;
|
refspecs = (const char **) argv;
|
||||||
nr_heads = argc - i;
|
nr_refspecs = argc - i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!dest)
|
if (!dest)
|
||||||
@@ -637,8 +530,8 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
|
|||||||
* --all and --mirror are incompatible; neither makes sense
|
* --all and --mirror are incompatible; neither makes sense
|
||||||
* with any refspecs.
|
* with any refspecs.
|
||||||
*/
|
*/
|
||||||
if ((heads && (args.send_all || args.send_mirror)) ||
|
if ((refspecs && (send_all || args.send_mirror)) ||
|
||||||
(args.send_all && args.send_mirror))
|
(send_all && args.send_mirror))
|
||||||
usage(send_pack_usage);
|
usage(send_pack_usage);
|
||||||
|
|
||||||
if (remote_name) {
|
if (remote_name) {
|
||||||
@@ -649,24 +542,50 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return send_pack(&args, dest, remote, nr_heads, heads);
|
conn = git_connect(fd, dest, receivepack, args.verbose ? CONNECT_VERBOSE : 0);
|
||||||
}
|
|
||||||
|
|
||||||
int send_pack(struct send_pack_args *my_args,
|
memset(&extra_have, 0, sizeof(extra_have));
|
||||||
const char *dest, struct remote *remote,
|
|
||||||
int nr_heads, const char **heads)
|
|
||||||
{
|
|
||||||
int fd[2], ret;
|
|
||||||
struct child_process *conn;
|
|
||||||
|
|
||||||
memcpy(&args, my_args, sizeof(args));
|
get_remote_heads(fd[0], &remote_refs, 0, NULL, REF_NORMAL,
|
||||||
|
&extra_have);
|
||||||
|
|
||||||
verify_remote_names(nr_heads, heads);
|
verify_remote_names(nr_refspecs, refspecs);
|
||||||
|
|
||||||
conn = git_connect(fd, dest, args.receivepack, args.verbose ? CONNECT_VERBOSE : 0);
|
local_refs = get_local_heads();
|
||||||
ret = do_send_pack(fd[0], fd[1], remote, dest, nr_heads, heads);
|
|
||||||
|
flags = MATCH_REFS_NONE;
|
||||||
|
|
||||||
|
if (send_all)
|
||||||
|
flags |= MATCH_REFS_ALL;
|
||||||
|
if (args.send_mirror)
|
||||||
|
flags |= MATCH_REFS_MIRROR;
|
||||||
|
|
||||||
|
/* match them up */
|
||||||
|
remote_tail = &remote_refs;
|
||||||
|
while (*remote_tail)
|
||||||
|
remote_tail = &((*remote_tail)->next);
|
||||||
|
if (match_refs(local_refs, remote_refs, &remote_tail,
|
||||||
|
nr_refspecs, refspecs, flags)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = send_pack(&args, fd, conn, remote_refs, &extra_have);
|
||||||
|
|
||||||
|
close(fd[1]);
|
||||||
close(fd[0]);
|
close(fd[0]);
|
||||||
/* do_send_pack always closes fd[1] */
|
|
||||||
ret |= finish_connect(conn);
|
ret |= finish_connect(conn);
|
||||||
return !!ret;
|
|
||||||
|
print_push_status(dest, remote_refs);
|
||||||
|
|
||||||
|
if (!args.dry_run && remote) {
|
||||||
|
struct ref *ref;
|
||||||
|
for (ref = remote_refs; ref; ref = ref->next)
|
||||||
|
update_tracking_ref(remote, ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ret && !refs_pushed(remote_refs))
|
||||||
|
fprintf(stderr, "Everything up-to-date\n");
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -365,8 +365,7 @@ static int append_ref(const char *refname, const unsigned char *sha1,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (MAX_REVS <= ref_name_cnt) {
|
if (MAX_REVS <= ref_name_cnt) {
|
||||||
fprintf(stderr, "warning: ignoring %s; "
|
warning("ignoring %s; cannot handle more than %d refs",
|
||||||
"cannot handle more than %d refs\n",
|
|
||||||
refname, MAX_REVS);
|
refname, MAX_REVS);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ static int exclude_existing(const char *match)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (check_ref_format(ref)) {
|
if (check_ref_format(ref)) {
|
||||||
fprintf(stderr, "warning: ref '%s' ignored\n", ref);
|
warning("ref '%s' ignored", ref);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!string_list_has_string(&existing_refs, ref)) {
|
if (!string_list_has_string(&existing_refs, ref)) {
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ static int process_path(const char *path)
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
len = strlen(path);
|
len = strlen(path);
|
||||||
if (has_symlink_leading_path(len, path))
|
if (has_symlink_leading_path(path, len))
|
||||||
return error("'%s' is beyond a symbolic link", path);
|
return error("'%s' is beyond a symbolic link", path);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
31
cache.h
31
cache.h
@@ -140,8 +140,8 @@ struct ondisk_cache_entry_extended {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct cache_entry {
|
struct cache_entry {
|
||||||
unsigned int ce_ctime;
|
struct cache_time ce_ctime;
|
||||||
unsigned int ce_mtime;
|
struct cache_time ce_mtime;
|
||||||
unsigned int ce_dev;
|
unsigned int ce_dev;
|
||||||
unsigned int ce_ino;
|
unsigned int ce_ino;
|
||||||
unsigned int ce_mode;
|
unsigned int ce_mode;
|
||||||
@@ -282,7 +282,7 @@ struct index_state {
|
|||||||
struct cache_entry **cache;
|
struct cache_entry **cache;
|
||||||
unsigned int cache_nr, cache_alloc, cache_changed;
|
unsigned int cache_nr, cache_alloc, cache_changed;
|
||||||
struct cache_tree *cache_tree;
|
struct cache_tree *cache_tree;
|
||||||
time_t timestamp;
|
struct cache_time timestamp;
|
||||||
void *alloc;
|
void *alloc;
|
||||||
unsigned name_hash_initialized : 1,
|
unsigned name_hash_initialized : 1,
|
||||||
initialized : 1;
|
initialized : 1;
|
||||||
@@ -428,7 +428,7 @@ extern int read_index_preload(struct index_state *, const char **pathspec);
|
|||||||
extern int read_index_from(struct index_state *, const char *path);
|
extern int read_index_from(struct index_state *, const char *path);
|
||||||
extern int is_index_unborn(struct index_state *);
|
extern int is_index_unborn(struct index_state *);
|
||||||
extern int read_index_unmerged(struct index_state *);
|
extern int read_index_unmerged(struct index_state *);
|
||||||
extern int write_index(const struct index_state *, int newfd);
|
extern int write_index(struct index_state *, int newfd);
|
||||||
extern int discard_index(struct index_state *);
|
extern int discard_index(struct index_state *);
|
||||||
extern int unmerged_index(const struct index_state *);
|
extern int unmerged_index(const struct index_state *);
|
||||||
extern int verify_path(const char *path);
|
extern int verify_path(const char *path);
|
||||||
@@ -443,6 +443,7 @@ extern int add_index_entry(struct index_state *, struct cache_entry *ce, int opt
|
|||||||
extern struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really);
|
extern struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really);
|
||||||
extern void rename_index_entry_at(struct index_state *, int pos, const char *new_name);
|
extern void rename_index_entry_at(struct index_state *, int pos, const char *new_name);
|
||||||
extern int remove_index_entry_at(struct index_state *, int pos);
|
extern int remove_index_entry_at(struct index_state *, int pos);
|
||||||
|
extern void remove_marked_cache_entries(struct index_state *istate);
|
||||||
extern int remove_file_from_index(struct index_state *, const char *path);
|
extern int remove_file_from_index(struct index_state *, const char *path);
|
||||||
#define ADD_CACHE_VERBOSE 1
|
#define ADD_CACHE_VERBOSE 1
|
||||||
#define ADD_CACHE_PRETEND 2
|
#define ADD_CACHE_PRETEND 2
|
||||||
@@ -541,8 +542,17 @@ enum rebase_setup_type {
|
|||||||
AUTOREBASE_ALWAYS,
|
AUTOREBASE_ALWAYS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum push_default_type {
|
||||||
|
PUSH_DEFAULT_UNSPECIFIED = -1,
|
||||||
|
PUSH_DEFAULT_NOTHING = 0,
|
||||||
|
PUSH_DEFAULT_MATCHING,
|
||||||
|
PUSH_DEFAULT_TRACKING,
|
||||||
|
PUSH_DEFAULT_CURRENT,
|
||||||
|
};
|
||||||
|
|
||||||
extern enum branch_track git_branch_track;
|
extern enum branch_track git_branch_track;
|
||||||
extern enum rebase_setup_type autorebase;
|
extern enum rebase_setup_type autorebase;
|
||||||
|
extern enum push_default_type push_default;
|
||||||
|
|
||||||
#define GIT_REPO_VERSION 0
|
#define GIT_REPO_VERSION 0
|
||||||
extern int repository_format_version;
|
extern int repository_format_version;
|
||||||
@@ -645,7 +655,6 @@ extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned l
|
|||||||
extern int move_temp_to_file(const char *tmpfile, const char *filename);
|
extern int move_temp_to_file(const char *tmpfile, const char *filename);
|
||||||
|
|
||||||
extern int has_sha1_pack(const unsigned char *sha1);
|
extern int has_sha1_pack(const unsigned char *sha1);
|
||||||
extern int has_sha1_kept_pack(const unsigned char *sha1);
|
|
||||||
extern int has_sha1_file(const unsigned char *sha1);
|
extern int has_sha1_file(const unsigned char *sha1);
|
||||||
extern int has_loose_object_nonlocal(const unsigned char *sha1);
|
extern int has_loose_object_nonlocal(const unsigned char *sha1);
|
||||||
|
|
||||||
@@ -725,11 +734,13 @@ struct checkout {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath);
|
extern int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath);
|
||||||
extern int has_symlink_leading_path(int len, const char *name);
|
extern int has_symlink_leading_path(const char *name, int len);
|
||||||
extern int has_symlink_or_noent_leading_path(int len, const char *name);
|
extern int has_symlink_or_noent_leading_path(const char *name, int len);
|
||||||
extern int has_dirs_only_path(int len, const char *name, int prefix_len);
|
extern int has_dirs_only_path(const char *name, int len, int prefix_len);
|
||||||
extern void invalidate_lstat_cache(int len, const char *name);
|
extern void invalidate_lstat_cache(const char *name, int len);
|
||||||
extern void clear_lstat_cache(void);
|
extern void clear_lstat_cache(void);
|
||||||
|
extern void schedule_dir_for_removal(const char *name, int len);
|
||||||
|
extern void remove_scheduled_dirs(void);
|
||||||
|
|
||||||
extern struct alternate_object_database {
|
extern struct alternate_object_database {
|
||||||
struct alternate_object_database *next;
|
struct alternate_object_database *next;
|
||||||
@@ -802,7 +813,7 @@ struct ref {
|
|||||||
#define REF_HEADS (1u << 1)
|
#define REF_HEADS (1u << 1)
|
||||||
#define REF_TAGS (1u << 2)
|
#define REF_TAGS (1u << 2)
|
||||||
|
|
||||||
extern struct ref *find_ref_by_name(struct ref *list, const char *name);
|
extern struct ref *find_ref_by_name(const struct ref *list, const char *name);
|
||||||
|
|
||||||
#define CONNECT_VERBOSE (1u << 0)
|
#define CONNECT_VERBOSE (1u << 0)
|
||||||
extern struct child_process *git_connect(int fd[2], const char *url, const char *prog, int flags);
|
extern struct child_process *git_connect(int fd[2], const char *url, const char *prog, int flags);
|
||||||
|
|||||||
@@ -712,9 +712,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
|
|||||||
result_size = buf.len;
|
result_size = buf.len;
|
||||||
result = strbuf_detach(&buf, NULL);
|
result = strbuf_detach(&buf, NULL);
|
||||||
elem->mode = canon_mode(st.st_mode);
|
elem->mode = canon_mode(st.st_mode);
|
||||||
}
|
} else if (0 <= (fd = open(elem->path, O_RDONLY))) {
|
||||||
else if (0 <= (fd = open(elem->path, O_RDONLY)) &&
|
|
||||||
!fstat(fd, &st)) {
|
|
||||||
size_t len = xsize_t(st.st_size);
|
size_t len = xsize_t(st.st_size);
|
||||||
ssize_t done;
|
ssize_t done;
|
||||||
int is_file, i;
|
int is_file, i;
|
||||||
|
|||||||
253
compat/mingw.c
253
compat/mingw.c
@@ -4,6 +4,119 @@
|
|||||||
|
|
||||||
unsigned int _CRT_fmode = _O_BINARY;
|
unsigned int _CRT_fmode = _O_BINARY;
|
||||||
|
|
||||||
|
static int err_win_to_posix(DWORD winerr)
|
||||||
|
{
|
||||||
|
int error = ENOSYS;
|
||||||
|
switch(winerr) {
|
||||||
|
case ERROR_ACCESS_DENIED: error = EACCES; break;
|
||||||
|
case ERROR_ACCOUNT_DISABLED: error = EACCES; break;
|
||||||
|
case ERROR_ACCOUNT_RESTRICTION: error = EACCES; break;
|
||||||
|
case ERROR_ALREADY_ASSIGNED: error = EBUSY; break;
|
||||||
|
case ERROR_ALREADY_EXISTS: error = EEXIST; break;
|
||||||
|
case ERROR_ARITHMETIC_OVERFLOW: error = ERANGE; break;
|
||||||
|
case ERROR_BAD_COMMAND: error = EIO; break;
|
||||||
|
case ERROR_BAD_DEVICE: error = ENODEV; break;
|
||||||
|
case ERROR_BAD_DRIVER_LEVEL: error = ENXIO; break;
|
||||||
|
case ERROR_BAD_EXE_FORMAT: error = ENOEXEC; break;
|
||||||
|
case ERROR_BAD_FORMAT: error = ENOEXEC; break;
|
||||||
|
case ERROR_BAD_LENGTH: error = EINVAL; break;
|
||||||
|
case ERROR_BAD_PATHNAME: error = ENOENT; break;
|
||||||
|
case ERROR_BAD_PIPE: error = EPIPE; break;
|
||||||
|
case ERROR_BAD_UNIT: error = ENODEV; break;
|
||||||
|
case ERROR_BAD_USERNAME: error = EINVAL; break;
|
||||||
|
case ERROR_BROKEN_PIPE: error = EPIPE; break;
|
||||||
|
case ERROR_BUFFER_OVERFLOW: error = ENAMETOOLONG; break;
|
||||||
|
case ERROR_BUSY: error = EBUSY; break;
|
||||||
|
case ERROR_BUSY_DRIVE: error = EBUSY; break;
|
||||||
|
case ERROR_CALL_NOT_IMPLEMENTED: error = ENOSYS; break;
|
||||||
|
case ERROR_CANNOT_MAKE: error = EACCES; break;
|
||||||
|
case ERROR_CANTOPEN: error = EIO; break;
|
||||||
|
case ERROR_CANTREAD: error = EIO; break;
|
||||||
|
case ERROR_CANTWRITE: error = EIO; break;
|
||||||
|
case ERROR_CRC: error = EIO; break;
|
||||||
|
case ERROR_CURRENT_DIRECTORY: error = EACCES; break;
|
||||||
|
case ERROR_DEVICE_IN_USE: error = EBUSY; break;
|
||||||
|
case ERROR_DEV_NOT_EXIST: error = ENODEV; break;
|
||||||
|
case ERROR_DIRECTORY: error = EINVAL; break;
|
||||||
|
case ERROR_DIR_NOT_EMPTY: error = ENOTEMPTY; break;
|
||||||
|
case ERROR_DISK_CHANGE: error = EIO; break;
|
||||||
|
case ERROR_DISK_FULL: error = ENOSPC; break;
|
||||||
|
case ERROR_DRIVE_LOCKED: error = EBUSY; break;
|
||||||
|
case ERROR_ENVVAR_NOT_FOUND: error = EINVAL; break;
|
||||||
|
case ERROR_EXE_MARKED_INVALID: error = ENOEXEC; break;
|
||||||
|
case ERROR_FILENAME_EXCED_RANGE: error = ENAMETOOLONG; break;
|
||||||
|
case ERROR_FILE_EXISTS: error = EEXIST; break;
|
||||||
|
case ERROR_FILE_INVALID: error = ENODEV; break;
|
||||||
|
case ERROR_FILE_NOT_FOUND: error = ENOENT; break;
|
||||||
|
case ERROR_GEN_FAILURE: error = EIO; break;
|
||||||
|
case ERROR_HANDLE_DISK_FULL: error = ENOSPC; break;
|
||||||
|
case ERROR_INSUFFICIENT_BUFFER: error = ENOMEM; break;
|
||||||
|
case ERROR_INVALID_ACCESS: error = EACCES; break;
|
||||||
|
case ERROR_INVALID_ADDRESS: error = EFAULT; break;
|
||||||
|
case ERROR_INVALID_BLOCK: error = EFAULT; break;
|
||||||
|
case ERROR_INVALID_DATA: error = EINVAL; break;
|
||||||
|
case ERROR_INVALID_DRIVE: error = ENODEV; break;
|
||||||
|
case ERROR_INVALID_EXE_SIGNATURE: error = ENOEXEC; break;
|
||||||
|
case ERROR_INVALID_FLAGS: error = EINVAL; break;
|
||||||
|
case ERROR_INVALID_FUNCTION: error = ENOSYS; break;
|
||||||
|
case ERROR_INVALID_HANDLE: error = EBADF; break;
|
||||||
|
case ERROR_INVALID_LOGON_HOURS: error = EACCES; break;
|
||||||
|
case ERROR_INVALID_NAME: error = EINVAL; break;
|
||||||
|
case ERROR_INVALID_OWNER: error = EINVAL; break;
|
||||||
|
case ERROR_INVALID_PARAMETER: error = EINVAL; break;
|
||||||
|
case ERROR_INVALID_PASSWORD: error = EPERM; break;
|
||||||
|
case ERROR_INVALID_PRIMARY_GROUP: error = EINVAL; break;
|
||||||
|
case ERROR_INVALID_SIGNAL_NUMBER: error = EINVAL; break;
|
||||||
|
case ERROR_INVALID_TARGET_HANDLE: error = EIO; break;
|
||||||
|
case ERROR_INVALID_WORKSTATION: error = EACCES; break;
|
||||||
|
case ERROR_IO_DEVICE: error = EIO; break;
|
||||||
|
case ERROR_IO_INCOMPLETE: error = EINTR; break;
|
||||||
|
case ERROR_LOCKED: error = EBUSY; break;
|
||||||
|
case ERROR_LOCK_VIOLATION: error = EACCES; break;
|
||||||
|
case ERROR_LOGON_FAILURE: error = EACCES; break;
|
||||||
|
case ERROR_MAPPED_ALIGNMENT: error = EINVAL; break;
|
||||||
|
case ERROR_META_EXPANSION_TOO_LONG: error = E2BIG; break;
|
||||||
|
case ERROR_MORE_DATA: error = EPIPE; break;
|
||||||
|
case ERROR_NEGATIVE_SEEK: error = ESPIPE; break;
|
||||||
|
case ERROR_NOACCESS: error = EFAULT; break;
|
||||||
|
case ERROR_NONE_MAPPED: error = EINVAL; break;
|
||||||
|
case ERROR_NOT_ENOUGH_MEMORY: error = ENOMEM; break;
|
||||||
|
case ERROR_NOT_READY: error = EAGAIN; break;
|
||||||
|
case ERROR_NOT_SAME_DEVICE: error = EXDEV; break;
|
||||||
|
case ERROR_NO_DATA: error = EPIPE; break;
|
||||||
|
case ERROR_NO_MORE_SEARCH_HANDLES: error = EIO; break;
|
||||||
|
case ERROR_NO_PROC_SLOTS: error = EAGAIN; break;
|
||||||
|
case ERROR_NO_SUCH_PRIVILEGE: error = EACCES; break;
|
||||||
|
case ERROR_OPEN_FAILED: error = EIO; break;
|
||||||
|
case ERROR_OPEN_FILES: error = EBUSY; break;
|
||||||
|
case ERROR_OPERATION_ABORTED: error = EINTR; break;
|
||||||
|
case ERROR_OUTOFMEMORY: error = ENOMEM; break;
|
||||||
|
case ERROR_PASSWORD_EXPIRED: error = EACCES; break;
|
||||||
|
case ERROR_PATH_BUSY: error = EBUSY; break;
|
||||||
|
case ERROR_PATH_NOT_FOUND: error = ENOENT; break;
|
||||||
|
case ERROR_PIPE_BUSY: error = EBUSY; break;
|
||||||
|
case ERROR_PIPE_CONNECTED: error = EPIPE; break;
|
||||||
|
case ERROR_PIPE_LISTENING: error = EPIPE; break;
|
||||||
|
case ERROR_PIPE_NOT_CONNECTED: error = EPIPE; break;
|
||||||
|
case ERROR_PRIVILEGE_NOT_HELD: error = EACCES; break;
|
||||||
|
case ERROR_READ_FAULT: error = EIO; break;
|
||||||
|
case ERROR_SEEK: error = EIO; break;
|
||||||
|
case ERROR_SEEK_ON_DEVICE: error = ESPIPE; break;
|
||||||
|
case ERROR_SHARING_BUFFER_EXCEEDED: error = ENFILE; break;
|
||||||
|
case ERROR_SHARING_VIOLATION: error = EACCES; break;
|
||||||
|
case ERROR_STACK_OVERFLOW: error = ENOMEM; break;
|
||||||
|
case ERROR_SWAPERROR: error = ENOENT; break;
|
||||||
|
case ERROR_TOO_MANY_MODULES: error = EMFILE; break;
|
||||||
|
case ERROR_TOO_MANY_OPEN_FILES: error = EMFILE; break;
|
||||||
|
case ERROR_UNRECOGNIZED_MEDIA: error = ENXIO; break;
|
||||||
|
case ERROR_UNRECOGNIZED_VOLUME: error = ENODEV; break;
|
||||||
|
case ERROR_WAIT_NO_CHILDREN: error = ECHILD; break;
|
||||||
|
case ERROR_WRITE_FAULT: error = EIO; break;
|
||||||
|
case ERROR_WRITE_PROTECT: error = EROFS; break;
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
#undef open
|
#undef open
|
||||||
int mingw_open (const char *filename, int oflags, ...)
|
int mingw_open (const char *filename, int oflags, ...)
|
||||||
{
|
{
|
||||||
@@ -344,7 +457,7 @@ static const char *quote_arg(const char *arg)
|
|||||||
const char *p = arg;
|
const char *p = arg;
|
||||||
if (!*p) force_quotes = 1;
|
if (!*p) force_quotes = 1;
|
||||||
while (*p) {
|
while (*p) {
|
||||||
if (isspace(*p) || *p == '*' || *p == '?' || *p == '{')
|
if (isspace(*p) || *p == '*' || *p == '?' || *p == '{' || *p == '\'')
|
||||||
force_quotes = 1;
|
force_quotes = 1;
|
||||||
else if (*p == '"')
|
else if (*p == '"')
|
||||||
n++;
|
n++;
|
||||||
@@ -821,7 +934,9 @@ int mingw_connect(int sockfd, struct sockaddr *sa, size_t sz)
|
|||||||
#undef rename
|
#undef rename
|
||||||
int mingw_rename(const char *pold, const char *pnew)
|
int mingw_rename(const char *pold, const char *pnew)
|
||||||
{
|
{
|
||||||
DWORD attrs;
|
DWORD attrs, gle;
|
||||||
|
int tries = 0;
|
||||||
|
static const int delay[] = { 0, 1, 10, 20, 40 };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try native rename() first to get errno right.
|
* Try native rename() first to get errno right.
|
||||||
@@ -831,10 +946,12 @@ int mingw_rename(const char *pold, const char *pnew)
|
|||||||
return 0;
|
return 0;
|
||||||
if (errno != EEXIST)
|
if (errno != EEXIST)
|
||||||
return -1;
|
return -1;
|
||||||
|
repeat:
|
||||||
if (MoveFileEx(pold, pnew, MOVEFILE_REPLACE_EXISTING))
|
if (MoveFileEx(pold, pnew, MOVEFILE_REPLACE_EXISTING))
|
||||||
return 0;
|
return 0;
|
||||||
/* TODO: translate more errors */
|
/* TODO: translate more errors */
|
||||||
if (GetLastError() == ERROR_ACCESS_DENIED &&
|
gle = GetLastError();
|
||||||
|
if (gle == ERROR_ACCESS_DENIED &&
|
||||||
(attrs = GetFileAttributes(pnew)) != INVALID_FILE_ATTRIBUTES) {
|
(attrs = GetFileAttributes(pnew)) != INVALID_FILE_ATTRIBUTES) {
|
||||||
if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
|
if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
errno = EISDIR;
|
errno = EISDIR;
|
||||||
@@ -844,10 +961,24 @@ int mingw_rename(const char *pold, const char *pnew)
|
|||||||
SetFileAttributes(pnew, attrs & ~FILE_ATTRIBUTE_READONLY)) {
|
SetFileAttributes(pnew, attrs & ~FILE_ATTRIBUTE_READONLY)) {
|
||||||
if (MoveFileEx(pold, pnew, MOVEFILE_REPLACE_EXISTING))
|
if (MoveFileEx(pold, pnew, MOVEFILE_REPLACE_EXISTING))
|
||||||
return 0;
|
return 0;
|
||||||
|
gle = GetLastError();
|
||||||
/* revert file attributes on failure */
|
/* revert file attributes on failure */
|
||||||
SetFileAttributes(pnew, attrs);
|
SetFileAttributes(pnew, attrs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (tries < ARRAY_SIZE(delay) && gle == ERROR_ACCESS_DENIED) {
|
||||||
|
/*
|
||||||
|
* We assume that some other process had the source or
|
||||||
|
* destination file open at the wrong moment and retry.
|
||||||
|
* In order to give the other process a higher chance to
|
||||||
|
* complete its operation, we give up our time slice now.
|
||||||
|
* If we have to retry again, we do sleep a bit.
|
||||||
|
*/
|
||||||
|
Sleep(delay[tries]);
|
||||||
|
tries++;
|
||||||
|
warning("rename retry #%d %s -> %s", tries, pold, pnew);
|
||||||
|
goto repeat;
|
||||||
|
}
|
||||||
errno = EACCES;
|
errno = EACCES;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1006,123 +1137,9 @@ void mingw_open_html(const char *unixpath)
|
|||||||
ShellExecute(NULL, "open", htmlpath, NULL, "\\", 0);
|
ShellExecute(NULL, "open", htmlpath, NULL, "\\", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int err_win_to_posix(DWORD winerr)
|
|
||||||
{
|
|
||||||
int error = ENOSYS;
|
|
||||||
switch(winerr) {
|
|
||||||
case ERROR_ACCESS_DENIED: error = EACCES; break;
|
|
||||||
case ERROR_ACCOUNT_DISABLED: error = EACCES; break;
|
|
||||||
case ERROR_ACCOUNT_RESTRICTION: error = EACCES; break;
|
|
||||||
case ERROR_ALREADY_ASSIGNED: error = EBUSY; break;
|
|
||||||
case ERROR_ALREADY_EXISTS: error = EEXIST; break;
|
|
||||||
case ERROR_ARITHMETIC_OVERFLOW: error = ERANGE; break;
|
|
||||||
case ERROR_BAD_COMMAND: error = EIO; break;
|
|
||||||
case ERROR_BAD_DEVICE: error = ENODEV; break;
|
|
||||||
case ERROR_BAD_DRIVER_LEVEL: error = ENXIO; break;
|
|
||||||
case ERROR_BAD_EXE_FORMAT: error = ENOEXEC; break;
|
|
||||||
case ERROR_BAD_FORMAT: error = ENOEXEC; break;
|
|
||||||
case ERROR_BAD_LENGTH: error = EINVAL; break;
|
|
||||||
case ERROR_BAD_PATHNAME: error = ENOENT; break;
|
|
||||||
case ERROR_BAD_PIPE: error = EPIPE; break;
|
|
||||||
case ERROR_BAD_UNIT: error = ENODEV; break;
|
|
||||||
case ERROR_BAD_USERNAME: error = EINVAL; break;
|
|
||||||
case ERROR_BROKEN_PIPE: error = EPIPE; break;
|
|
||||||
case ERROR_BUFFER_OVERFLOW: error = ENAMETOOLONG; break;
|
|
||||||
case ERROR_BUSY: error = EBUSY; break;
|
|
||||||
case ERROR_BUSY_DRIVE: error = EBUSY; break;
|
|
||||||
case ERROR_CALL_NOT_IMPLEMENTED: error = ENOSYS; break;
|
|
||||||
case ERROR_CANNOT_MAKE: error = EACCES; break;
|
|
||||||
case ERROR_CANTOPEN: error = EIO; break;
|
|
||||||
case ERROR_CANTREAD: error = EIO; break;
|
|
||||||
case ERROR_CANTWRITE: error = EIO; break;
|
|
||||||
case ERROR_CRC: error = EIO; break;
|
|
||||||
case ERROR_CURRENT_DIRECTORY: error = EACCES; break;
|
|
||||||
case ERROR_DEVICE_IN_USE: error = EBUSY; break;
|
|
||||||
case ERROR_DEV_NOT_EXIST: error = ENODEV; break;
|
|
||||||
case ERROR_DIRECTORY: error = EINVAL; break;
|
|
||||||
case ERROR_DIR_NOT_EMPTY: error = ENOTEMPTY; break;
|
|
||||||
case ERROR_DISK_CHANGE: error = EIO; break;
|
|
||||||
case ERROR_DISK_FULL: error = ENOSPC; break;
|
|
||||||
case ERROR_DRIVE_LOCKED: error = EBUSY; break;
|
|
||||||
case ERROR_ENVVAR_NOT_FOUND: error = EINVAL; break;
|
|
||||||
case ERROR_EXE_MARKED_INVALID: error = ENOEXEC; break;
|
|
||||||
case ERROR_FILENAME_EXCED_RANGE: error = ENAMETOOLONG; break;
|
|
||||||
case ERROR_FILE_EXISTS: error = EEXIST; break;
|
|
||||||
case ERROR_FILE_INVALID: error = ENODEV; break;
|
|
||||||
case ERROR_FILE_NOT_FOUND: error = ENOENT; break;
|
|
||||||
case ERROR_GEN_FAILURE: error = EIO; break;
|
|
||||||
case ERROR_HANDLE_DISK_FULL: error = ENOSPC; break;
|
|
||||||
case ERROR_INSUFFICIENT_BUFFER: error = ENOMEM; break;
|
|
||||||
case ERROR_INVALID_ACCESS: error = EACCES; break;
|
|
||||||
case ERROR_INVALID_ADDRESS: error = EFAULT; break;
|
|
||||||
case ERROR_INVALID_BLOCK: error = EFAULT; break;
|
|
||||||
case ERROR_INVALID_DATA: error = EINVAL; break;
|
|
||||||
case ERROR_INVALID_DRIVE: error = ENODEV; break;
|
|
||||||
case ERROR_INVALID_EXE_SIGNATURE: error = ENOEXEC; break;
|
|
||||||
case ERROR_INVALID_FLAGS: error = EINVAL; break;
|
|
||||||
case ERROR_INVALID_FUNCTION: error = ENOSYS; break;
|
|
||||||
case ERROR_INVALID_HANDLE: error = EBADF; break;
|
|
||||||
case ERROR_INVALID_LOGON_HOURS: error = EACCES; break;
|
|
||||||
case ERROR_INVALID_NAME: error = EINVAL; break;
|
|
||||||
case ERROR_INVALID_OWNER: error = EINVAL; break;
|
|
||||||
case ERROR_INVALID_PARAMETER: error = EINVAL; break;
|
|
||||||
case ERROR_INVALID_PASSWORD: error = EPERM; break;
|
|
||||||
case ERROR_INVALID_PRIMARY_GROUP: error = EINVAL; break;
|
|
||||||
case ERROR_INVALID_SIGNAL_NUMBER: error = EINVAL; break;
|
|
||||||
case ERROR_INVALID_TARGET_HANDLE: error = EIO; break;
|
|
||||||
case ERROR_INVALID_WORKSTATION: error = EACCES; break;
|
|
||||||
case ERROR_IO_DEVICE: error = EIO; break;
|
|
||||||
case ERROR_IO_INCOMPLETE: error = EINTR; break;
|
|
||||||
case ERROR_LOCKED: error = EBUSY; break;
|
|
||||||
case ERROR_LOCK_VIOLATION: error = EACCES; break;
|
|
||||||
case ERROR_LOGON_FAILURE: error = EACCES; break;
|
|
||||||
case ERROR_MAPPED_ALIGNMENT: error = EINVAL; break;
|
|
||||||
case ERROR_META_EXPANSION_TOO_LONG: error = E2BIG; break;
|
|
||||||
case ERROR_MORE_DATA: error = EPIPE; break;
|
|
||||||
case ERROR_NEGATIVE_SEEK: error = ESPIPE; break;
|
|
||||||
case ERROR_NOACCESS: error = EFAULT; break;
|
|
||||||
case ERROR_NONE_MAPPED: error = EINVAL; break;
|
|
||||||
case ERROR_NOT_ENOUGH_MEMORY: error = ENOMEM; break;
|
|
||||||
case ERROR_NOT_READY: error = EAGAIN; break;
|
|
||||||
case ERROR_NOT_SAME_DEVICE: error = EXDEV; break;
|
|
||||||
case ERROR_NO_DATA: error = EPIPE; break;
|
|
||||||
case ERROR_NO_MORE_SEARCH_HANDLES: error = EIO; break;
|
|
||||||
case ERROR_NO_PROC_SLOTS: error = EAGAIN; break;
|
|
||||||
case ERROR_NO_SUCH_PRIVILEGE: error = EACCES; break;
|
|
||||||
case ERROR_OPEN_FAILED: error = EIO; break;
|
|
||||||
case ERROR_OPEN_FILES: error = EBUSY; break;
|
|
||||||
case ERROR_OPERATION_ABORTED: error = EINTR; break;
|
|
||||||
case ERROR_OUTOFMEMORY: error = ENOMEM; break;
|
|
||||||
case ERROR_PASSWORD_EXPIRED: error = EACCES; break;
|
|
||||||
case ERROR_PATH_BUSY: error = EBUSY; break;
|
|
||||||
case ERROR_PATH_NOT_FOUND: error = ENOENT; break;
|
|
||||||
case ERROR_PIPE_BUSY: error = EBUSY; break;
|
|
||||||
case ERROR_PIPE_CONNECTED: error = EPIPE; break;
|
|
||||||
case ERROR_PIPE_LISTENING: error = EPIPE; break;
|
|
||||||
case ERROR_PIPE_NOT_CONNECTED: error = EPIPE; break;
|
|
||||||
case ERROR_PRIVILEGE_NOT_HELD: error = EACCES; break;
|
|
||||||
case ERROR_READ_FAULT: error = EIO; break;
|
|
||||||
case ERROR_SEEK: error = EIO; break;
|
|
||||||
case ERROR_SEEK_ON_DEVICE: error = ESPIPE; break;
|
|
||||||
case ERROR_SHARING_BUFFER_EXCEEDED: error = ENFILE; break;
|
|
||||||
case ERROR_SHARING_VIOLATION: error = EACCES; break;
|
|
||||||
case ERROR_STACK_OVERFLOW: error = ENOMEM; break;
|
|
||||||
case ERROR_SWAPERROR: error = ENOENT; break;
|
|
||||||
case ERROR_TOO_MANY_MODULES: error = EMFILE; break;
|
|
||||||
case ERROR_TOO_MANY_OPEN_FILES: error = EMFILE; break;
|
|
||||||
case ERROR_UNRECOGNIZED_MEDIA: error = ENXIO; break;
|
|
||||||
case ERROR_UNRECOGNIZED_VOLUME: error = ENODEV; break;
|
|
||||||
case ERROR_WAIT_NO_CHILDREN: error = ECHILD; break;
|
|
||||||
case ERROR_WRITE_FAULT: error = EIO; break;
|
|
||||||
case ERROR_WRITE_PROTECT: error = EROFS; break;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int link(const char *oldpath, const char *newpath)
|
int link(const char *oldpath, const char *newpath)
|
||||||
{
|
{
|
||||||
typedef BOOL WINAPI (*T)(LPCTSTR, LPCTSTR, LPSECURITY_ATTRIBUTES);
|
typedef BOOL WINAPI (*T)(const char*, const char*, LPSECURITY_ATTRIBUTES);
|
||||||
static T create_hard_link = NULL;
|
static T create_hard_link = NULL;
|
||||||
if (!create_hard_link) {
|
if (!create_hard_link) {
|
||||||
create_hard_link = (T) GetProcAddress(
|
create_hard_link = (T) GetProcAddress(
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "../git-compat-util.h"
|
#include "../git-compat-util.h"
|
||||||
|
|
||||||
/* Note that this doesn't return the actual pagesize, but
|
/*
|
||||||
|
* Note that this doesn't return the actual pagesize, but
|
||||||
* the allocation granularity. If future Windows specific git code
|
* the allocation granularity. If future Windows specific git code
|
||||||
* needs the real getpagesize function, we need to find another solution.
|
* needs the real getpagesize function, we need to find another solution.
|
||||||
*/
|
*/
|
||||||
@@ -11,8 +12,7 @@ int mingw_getpagesize(void)
|
|||||||
return si.dwAllocationGranularity;
|
return si.dwAllocationGranularity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *git_mmap
|
void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
|
||||||
(void *start, size_t length, int prot, int flags, int fd, off_t offset)
|
|
||||||
{
|
{
|
||||||
HANDLE hmap;
|
HANDLE hmap;
|
||||||
void *temp;
|
void *temp;
|
||||||
|
|||||||
45
config.c
45
config.c
@@ -565,6 +565,31 @@ static int git_default_branch_config(const char *var, const char *value)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int git_default_push_config(const char *var, const char *value)
|
||||||
|
{
|
||||||
|
if (!strcmp(var, "push.default")) {
|
||||||
|
if (!value)
|
||||||
|
return config_error_nonbool(var);
|
||||||
|
else if (!strcmp(value, "nothing"))
|
||||||
|
push_default = PUSH_DEFAULT_NOTHING;
|
||||||
|
else if (!strcmp(value, "matching"))
|
||||||
|
push_default = PUSH_DEFAULT_MATCHING;
|
||||||
|
else if (!strcmp(value, "tracking"))
|
||||||
|
push_default = PUSH_DEFAULT_TRACKING;
|
||||||
|
else if (!strcmp(value, "current"))
|
||||||
|
push_default = PUSH_DEFAULT_CURRENT;
|
||||||
|
else {
|
||||||
|
error("Malformed value for %s: %s", var, value);
|
||||||
|
return error("Must be one of nothing, matching, "
|
||||||
|
"tracking or current.");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add other config variables here and to Documentation/config.txt. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int git_default_mailmap_config(const char *var, const char *value)
|
static int git_default_mailmap_config(const char *var, const char *value)
|
||||||
{
|
{
|
||||||
if (!strcmp(var, "mailmap.file"))
|
if (!strcmp(var, "mailmap.file"))
|
||||||
@@ -588,6 +613,9 @@ int git_default_config(const char *var, const char *value, void *dummy)
|
|||||||
if (!prefixcmp(var, "branch."))
|
if (!prefixcmp(var, "branch."))
|
||||||
return git_default_branch_config(var, value);
|
return git_default_branch_config(var, value);
|
||||||
|
|
||||||
|
if (!prefixcmp(var, "push."))
|
||||||
|
return git_default_push_config(var, value);
|
||||||
|
|
||||||
if (!prefixcmp(var, "mailmap."))
|
if (!prefixcmp(var, "mailmap."))
|
||||||
return git_default_mailmap_config(var, value);
|
return git_default_mailmap_config(var, value);
|
||||||
|
|
||||||
@@ -644,28 +672,37 @@ int git_config_global(void)
|
|||||||
|
|
||||||
int git_config(config_fn_t fn, void *data)
|
int git_config(config_fn_t fn, void *data)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0, found = 0;
|
||||||
char *repo_config = NULL;
|
char *repo_config = NULL;
|
||||||
const char *home = NULL;
|
const char *home = NULL;
|
||||||
|
|
||||||
/* Setting $GIT_CONFIG makes git read _only_ the given config file. */
|
/* Setting $GIT_CONFIG makes git read _only_ the given config file. */
|
||||||
if (config_exclusive_filename)
|
if (config_exclusive_filename)
|
||||||
return git_config_from_file(fn, config_exclusive_filename, data);
|
return git_config_from_file(fn, config_exclusive_filename, data);
|
||||||
if (git_config_system() && !access(git_etc_gitconfig(), R_OK))
|
if (git_config_system() && !access(git_etc_gitconfig(), R_OK)) {
|
||||||
ret += git_config_from_file(fn, git_etc_gitconfig(),
|
ret += git_config_from_file(fn, git_etc_gitconfig(),
|
||||||
data);
|
data);
|
||||||
|
found += 1;
|
||||||
|
}
|
||||||
|
|
||||||
home = getenv("HOME");
|
home = getenv("HOME");
|
||||||
if (git_config_global() && home) {
|
if (git_config_global() && home) {
|
||||||
char *user_config = xstrdup(mkpath("%s/.gitconfig", home));
|
char *user_config = xstrdup(mkpath("%s/.gitconfig", home));
|
||||||
if (!access(user_config, R_OK))
|
if (!access(user_config, R_OK)) {
|
||||||
ret += git_config_from_file(fn, user_config, data);
|
ret += git_config_from_file(fn, user_config, data);
|
||||||
|
found += 1;
|
||||||
|
}
|
||||||
free(user_config);
|
free(user_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
repo_config = git_pathdup("config");
|
repo_config = git_pathdup("config");
|
||||||
ret += git_config_from_file(fn, repo_config, data);
|
if (!access(repo_config, R_OK)) {
|
||||||
|
ret += git_config_from_file(fn, repo_config, data);
|
||||||
|
found += 1;
|
||||||
|
}
|
||||||
free(repo_config);
|
free(repo_config);
|
||||||
|
if (found == 0)
|
||||||
|
return -1;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
386
configure.ac
386
configure.ac
@@ -42,6 +42,8 @@ else \
|
|||||||
if test "$withval" = "yes"; then \
|
if test "$withval" = "yes"; then \
|
||||||
AC_MSG_WARN([You should provide path for --with-$1=PATH]); \
|
AC_MSG_WARN([You should provide path for --with-$1=PATH]); \
|
||||||
else \
|
else \
|
||||||
|
m4_toupper($1)_PATH=$withval; \
|
||||||
|
AC_MSG_NOTICE([Setting m4_toupper($1)_PATH to $withval]); \
|
||||||
GIT_CONF_APPEND_LINE(${PROGRAM}_PATH=$withval); \
|
GIT_CONF_APPEND_LINE(${PROGRAM}_PATH=$withval); \
|
||||||
fi; \
|
fi; \
|
||||||
fi; \
|
fi; \
|
||||||
@@ -61,6 +63,8 @@ elif test "$withval" = "yes"; then \
|
|||||||
m4_toupper(NO_$1)=; \
|
m4_toupper(NO_$1)=; \
|
||||||
else \
|
else \
|
||||||
m4_toupper(NO_$1)=; \
|
m4_toupper(NO_$1)=; \
|
||||||
|
m4_toupper($1)DIR=$withval; \
|
||||||
|
AC_MSG_NOTICE([Setting m4_toupper($1)DIR to $withval]); \
|
||||||
GIT_CONF_APPEND_LINE(${PACKAGE}DIR=$withval); \
|
GIT_CONF_APPEND_LINE(${PACKAGE}DIR=$withval); \
|
||||||
fi \
|
fi \
|
||||||
])# GIT_PARSE_WITH
|
])# GIT_PARSE_WITH
|
||||||
@@ -76,6 +80,32 @@ AC_DEFUN([GIT_CHECK_FUNC],[AC_CHECK_FUNC([$1],[
|
|||||||
AC_SEARCH_LIBS([$1],,
|
AC_SEARCH_LIBS([$1],,
|
||||||
[$2],[$3])
|
[$2],[$3])
|
||||||
],[$3])])
|
],[$3])])
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl GIT_STASH_FLAGS(BASEPATH_VAR)
|
||||||
|
dnl -----------------------------
|
||||||
|
dnl Allow for easy stashing of LDFLAGS and CPPFLAGS before running
|
||||||
|
dnl tests that may want to take user settings into account.
|
||||||
|
AC_DEFUN([GIT_STASH_FLAGS],[
|
||||||
|
if test -n "$1"; then
|
||||||
|
old_CPPFLAGS="$CPPFLAGS"
|
||||||
|
old_LDFLAGS="$LDFLAGS"
|
||||||
|
CPPFLAGS="-I$1/include $CPPFLAGS"
|
||||||
|
LDFLAGS="-L$1/$lib $LDFLAGS"
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl GIT_UNSTASH_FLAGS(BASEPATH_VAR)
|
||||||
|
dnl -----------------------------
|
||||||
|
dnl Restore the stashed *FLAGS values.
|
||||||
|
AC_DEFUN([GIT_UNSTASH_FLAGS],[
|
||||||
|
if test -n "$1"; then
|
||||||
|
CPPFLAGS="$old_CPPFLAGS"
|
||||||
|
LDFLAGS="$old_LDFLAGS"
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
## Site configuration related to programs (before tests)
|
## Site configuration related to programs (before tests)
|
||||||
## --with-PACKAGE[=ARG] and --without-PACKAGE
|
## --with-PACKAGE[=ARG] and --without-PACKAGE
|
||||||
#
|
#
|
||||||
@@ -86,9 +116,124 @@ AC_ARG_WITH([lib],
|
|||||||
[if test "$withval" = "no" || test "$withval" = "yes"; then \
|
[if test "$withval" = "no" || test "$withval" = "yes"; then \
|
||||||
AC_MSG_WARN([You should provide name for --with-lib=ARG]); \
|
AC_MSG_WARN([You should provide name for --with-lib=ARG]); \
|
||||||
else \
|
else \
|
||||||
|
lib=$withval; \
|
||||||
|
AC_MSG_NOTICE([Setting lib to '$lib']); \
|
||||||
GIT_CONF_APPEND_LINE(lib=$withval); \
|
GIT_CONF_APPEND_LINE(lib=$withval); \
|
||||||
fi; \
|
fi; \
|
||||||
],[])
|
],[])
|
||||||
|
|
||||||
|
if test -z "$lib"; then
|
||||||
|
AC_MSG_NOTICE([Setting lib to 'lib' (the default)])
|
||||||
|
lib=lib
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([pthreads],
|
||||||
|
[AS_HELP_STRING([--enable-pthreads=FLAGS],
|
||||||
|
[FLAGS is the value to pass to the compiler to enable POSIX Threads.]
|
||||||
|
[The default if FLAGS is not specified is to try first -pthread]
|
||||||
|
[and then -lpthread.]
|
||||||
|
[--without-pthreads will disable threading.])],
|
||||||
|
[
|
||||||
|
if test "x$enableval" = "xyes"; then
|
||||||
|
AC_MSG_NOTICE([Will try -pthread then -lpthread to enable POSIX Threads])
|
||||||
|
elif test "x$enableval" != "xno"; then
|
||||||
|
PTHREAD_CFLAGS=$enableval
|
||||||
|
AC_MSG_NOTICE([Setting '$PTHREAD_CFLAGS' as the FLAGS to enable POSIX Threads])
|
||||||
|
else
|
||||||
|
AC_MSG_NOTICE([POSIX Threads will be disabled.])
|
||||||
|
NO_PTHREADS=YesPlease
|
||||||
|
USER_NOPTHREAD=1
|
||||||
|
fi],
|
||||||
|
[
|
||||||
|
AC_MSG_NOTICE([Will try -pthread then -lpthread to enable POSIX Threads.])
|
||||||
|
])
|
||||||
|
|
||||||
|
## Site configuration (override autodetection)
|
||||||
|
## --with-PACKAGE[=ARG] and --without-PACKAGE
|
||||||
|
AC_MSG_NOTICE([CHECKS for site configuration])
|
||||||
|
#
|
||||||
|
# Define NO_SVN_TESTS if you want to skip time-consuming SVN interoperability
|
||||||
|
# tests. These tests take up a significant amount of the total test time
|
||||||
|
# but are not needed unless you plan to talk to SVN repos.
|
||||||
|
#
|
||||||
|
# Define MOZILLA_SHA1 environment variable when running make to make use of
|
||||||
|
# a bundled SHA1 routine coming from Mozilla. It is GPL'd and should be fast
|
||||||
|
# on non-x86 architectures (e.g. PowerPC), while the OpenSSL version (default
|
||||||
|
# choice) has very fast version optimized for i586.
|
||||||
|
#
|
||||||
|
# Define PPC_SHA1 environment variable when running make to make use of
|
||||||
|
# a bundled SHA1 routine optimized for PowerPC.
|
||||||
|
#
|
||||||
|
# Define ARM_SHA1 environment variable when running make to make use of
|
||||||
|
# a bundled SHA1 routine optimized for ARM.
|
||||||
|
#
|
||||||
|
# Define NO_OPENSSL environment variable if you do not have OpenSSL.
|
||||||
|
# This also implies MOZILLA_SHA1.
|
||||||
|
#
|
||||||
|
# Define OPENSSLDIR=/foo/bar if your openssl header and library files are in
|
||||||
|
# /foo/bar/include and /foo/bar/lib directories.
|
||||||
|
AC_ARG_WITH(openssl,
|
||||||
|
AS_HELP_STRING([--with-openssl],[use OpenSSL library (default is YES)])
|
||||||
|
AS_HELP_STRING([], [ARG can be prefix for openssl library and headers]),\
|
||||||
|
GIT_PARSE_WITH(openssl))
|
||||||
|
#
|
||||||
|
# Define NO_CURL if you do not have curl installed. git-http-pull and
|
||||||
|
# git-http-push are not built, and you cannot use http:// and https://
|
||||||
|
# transports.
|
||||||
|
#
|
||||||
|
# Define CURLDIR=/foo/bar if your curl header and library files are in
|
||||||
|
# /foo/bar/include and /foo/bar/lib directories.
|
||||||
|
AC_ARG_WITH(curl,
|
||||||
|
AS_HELP_STRING([--with-curl],[support http(s):// transports (default is YES)])
|
||||||
|
AS_HELP_STRING([], [ARG can be also prefix for curl library and headers]),
|
||||||
|
GIT_PARSE_WITH(curl))
|
||||||
|
#
|
||||||
|
# Define NO_EXPAT if you do not have expat installed. git-http-push is
|
||||||
|
# not built, and you cannot push using http:// and https:// transports.
|
||||||
|
#
|
||||||
|
# Define EXPATDIR=/foo/bar if your expat header and library files are in
|
||||||
|
# /foo/bar/include and /foo/bar/lib directories.
|
||||||
|
AC_ARG_WITH(expat,
|
||||||
|
AS_HELP_STRING([--with-expat],
|
||||||
|
[support git-push using http:// and https:// transports via WebDAV (default is YES)])
|
||||||
|
AS_HELP_STRING([], [ARG can be also prefix for expat library and headers]),
|
||||||
|
GIT_PARSE_WITH(expat))
|
||||||
|
#
|
||||||
|
# Define NO_FINK if you are building on Darwin/Mac OS X, have Fink
|
||||||
|
# installed in /sw, but don't want GIT to link against any libraries
|
||||||
|
# installed there. If defined you may specify your own (or Fink's)
|
||||||
|
# include directories and library directories by defining CFLAGS
|
||||||
|
# and LDFLAGS appropriately.
|
||||||
|
#
|
||||||
|
# Define NO_DARWIN_PORTS if you are building on Darwin/Mac OS X,
|
||||||
|
# have DarwinPorts installed in /opt/local, but don't want GIT to
|
||||||
|
# link against any libraries installed there. If defined you may
|
||||||
|
# specify your own (or DarwinPort's) include directories and
|
||||||
|
# library directories by defining CFLAGS and LDFLAGS appropriately.
|
||||||
|
#
|
||||||
|
# Define NO_MMAP if you want to avoid mmap.
|
||||||
|
#
|
||||||
|
# Define NO_ICONV if your libc does not properly support iconv.
|
||||||
|
AC_ARG_WITH(iconv,
|
||||||
|
AS_HELP_STRING([--without-iconv],
|
||||||
|
[if your architecture doesn't properly support iconv])
|
||||||
|
AS_HELP_STRING([--with-iconv=PATH],
|
||||||
|
[PATH is prefix for libiconv library and headers])
|
||||||
|
AS_HELP_STRING([],
|
||||||
|
[used only if you need linking with libiconv]),
|
||||||
|
GIT_PARSE_WITH(iconv))
|
||||||
|
|
||||||
|
## --enable-FEATURE[=ARG] and --disable-FEATURE
|
||||||
|
#
|
||||||
|
# Define USE_NSEC below if you want git to care about sub-second file mtimes
|
||||||
|
# and ctimes. Note that you need recent glibc (at least 2.2.4) for this, and
|
||||||
|
# it will BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely
|
||||||
|
# randomly break unless your underlying filesystem supports those sub-second
|
||||||
|
# times (my ext3 doesn't).
|
||||||
|
#
|
||||||
|
# Define USE_STDEV below if you want git to care about the underlying device
|
||||||
|
# change being considered an inode change from the update-index perspective.
|
||||||
|
|
||||||
#
|
#
|
||||||
# Define SHELL_PATH to provide path to shell.
|
# Define SHELL_PATH to provide path to shell.
|
||||||
GIT_ARG_SET_PATH(shell)
|
GIT_ARG_SET_PATH(shell)
|
||||||
@@ -167,7 +312,7 @@ fi
|
|||||||
AC_CHECK_PROGS(ASCIIDOC, [asciidoc])
|
AC_CHECK_PROGS(ASCIIDOC, [asciidoc])
|
||||||
if test -n "$ASCIIDOC"; then
|
if test -n "$ASCIIDOC"; then
|
||||||
AC_MSG_CHECKING([for asciidoc version])
|
AC_MSG_CHECKING([for asciidoc version])
|
||||||
asciidoc_version=`$ASCIIDOC --version 2>&1`
|
asciidoc_version=`$ASCIIDOC --version 2>/dev/null`
|
||||||
case "${asciidoc_version}" in
|
case "${asciidoc_version}" in
|
||||||
asciidoc' '8*)
|
asciidoc' '8*)
|
||||||
ASCIIDOC8=YesPlease
|
ASCIIDOC8=YesPlease
|
||||||
@@ -191,33 +336,57 @@ AC_MSG_NOTICE([CHECKS for libraries])
|
|||||||
#
|
#
|
||||||
# Define NO_OPENSSL environment variable if you do not have OpenSSL.
|
# Define NO_OPENSSL environment variable if you do not have OpenSSL.
|
||||||
# Define NEEDS_SSL_WITH_CRYPTO if you need -lcrypto with -lssl (Darwin).
|
# Define NEEDS_SSL_WITH_CRYPTO if you need -lcrypto with -lssl (Darwin).
|
||||||
|
|
||||||
|
GIT_STASH_FLAGS($OPENSSLDIR)
|
||||||
|
|
||||||
AC_CHECK_LIB([crypto], [SHA1_Init],
|
AC_CHECK_LIB([crypto], [SHA1_Init],
|
||||||
[NEEDS_SSL_WITH_CRYPTO=],
|
[NEEDS_SSL_WITH_CRYPTO=],
|
||||||
[AC_CHECK_LIB([ssl], [SHA1_Init],
|
[AC_CHECK_LIB([ssl], [SHA1_Init],
|
||||||
[NEEDS_SSL_WITH_CRYPTO=YesPlease
|
[NEEDS_SSL_WITH_CRYPTO=YesPlease
|
||||||
NEEDS_SSL_WITH_CRYPTO=],
|
NEEDS_SSL_WITH_CRYPTO=],
|
||||||
[NO_OPENSSL=YesPlease])])
|
[NO_OPENSSL=YesPlease])])
|
||||||
|
|
||||||
|
GIT_UNSTASH_FLAGS($OPENSSLDIR)
|
||||||
|
|
||||||
AC_SUBST(NEEDS_SSL_WITH_CRYPTO)
|
AC_SUBST(NEEDS_SSL_WITH_CRYPTO)
|
||||||
AC_SUBST(NO_OPENSSL)
|
AC_SUBST(NO_OPENSSL)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Define NO_CURL if you do not have libcurl installed. git-http-pull and
|
# Define NO_CURL if you do not have libcurl installed. git-http-pull and
|
||||||
# git-http-push are not built, and you cannot use http:// and https://
|
# git-http-push are not built, and you cannot use http:// and https://
|
||||||
# transports.
|
# transports.
|
||||||
|
|
||||||
|
GIT_STASH_FLAGS($CURLDIR)
|
||||||
|
|
||||||
AC_CHECK_LIB([curl], [curl_global_init],
|
AC_CHECK_LIB([curl], [curl_global_init],
|
||||||
[NO_CURL=],
|
[NO_CURL=],
|
||||||
[NO_CURL=YesPlease])
|
[NO_CURL=YesPlease])
|
||||||
|
|
||||||
|
GIT_UNSTASH_FLAGS($CURLDIR)
|
||||||
|
|
||||||
AC_SUBST(NO_CURL)
|
AC_SUBST(NO_CURL)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Define NO_EXPAT if you do not have expat installed. git-http-push is
|
# Define NO_EXPAT if you do not have expat installed. git-http-push is
|
||||||
# not built, and you cannot push using http:// and https:// transports.
|
# not built, and you cannot push using http:// and https:// transports.
|
||||||
|
|
||||||
|
GIT_STASH_FLAGS($EXPATDIR)
|
||||||
|
|
||||||
AC_CHECK_LIB([expat], [XML_ParserCreate],
|
AC_CHECK_LIB([expat], [XML_ParserCreate],
|
||||||
[NO_EXPAT=],
|
[NO_EXPAT=],
|
||||||
[NO_EXPAT=YesPlease])
|
[NO_EXPAT=YesPlease])
|
||||||
|
|
||||||
|
GIT_UNSTASH_FLAGS($EXPATDIR)
|
||||||
|
|
||||||
AC_SUBST(NO_EXPAT)
|
AC_SUBST(NO_EXPAT)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Define NEEDS_LIBICONV if linking with libc is not enough (Darwin and
|
# Define NEEDS_LIBICONV if linking with libc is not enough (Darwin and
|
||||||
# some Solaris installations).
|
# some Solaris installations).
|
||||||
# Define NO_ICONV if neither libc nor libiconv support iconv.
|
# Define NO_ICONV if neither libc nor libiconv support iconv.
|
||||||
|
|
||||||
|
GIT_STASH_FLAGS($ICONVDIR)
|
||||||
|
|
||||||
AC_DEFUN([ICONVTEST_SRC], [
|
AC_DEFUN([ICONVTEST_SRC], [
|
||||||
#include <iconv.h>
|
#include <iconv.h>
|
||||||
|
|
||||||
@@ -227,25 +396,46 @@ int main(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
AC_MSG_CHECKING([for iconv in -lc])
|
|
||||||
AC_LINK_IFELSE(ICONVTEST_SRC,
|
if test -n "$ICONVDIR"; then
|
||||||
|
lib_order="-liconv -lc"
|
||||||
|
else
|
||||||
|
lib_order="-lc -liconv"
|
||||||
|
fi
|
||||||
|
|
||||||
|
NO_ICONV=YesPlease
|
||||||
|
|
||||||
|
for l in $lib_order; do
|
||||||
|
if test "$l" = "-liconv"; then
|
||||||
|
NEEDS_LIBICONV=YesPlease
|
||||||
|
else
|
||||||
|
NEEDS_LIBICONV=
|
||||||
|
fi
|
||||||
|
|
||||||
|
old_LIBS="$LIBS"
|
||||||
|
LIBS="$LIBS $l"
|
||||||
|
AC_MSG_CHECKING([for iconv in $l])
|
||||||
|
AC_LINK_IFELSE(ICONVTEST_SRC,
|
||||||
[AC_MSG_RESULT([yes])
|
[AC_MSG_RESULT([yes])
|
||||||
NEEDS_LIBICONV=],
|
NO_ICONV=
|
||||||
[AC_MSG_RESULT([no])
|
break],
|
||||||
old_LIBS="$LIBS"
|
[AC_MSG_RESULT([no])])
|
||||||
LIBS="$LIBS -liconv"
|
LIBS="$old_LIBS"
|
||||||
AC_MSG_CHECKING([for iconv in -liconv])
|
done
|
||||||
AC_LINK_IFELSE(ICONVTEST_SRC,
|
|
||||||
[AC_MSG_RESULT([yes])
|
#in case of break
|
||||||
NEEDS_LIBICONV=YesPlease],
|
LIBS="$old_LIBS"
|
||||||
[AC_MSG_RESULT([no])
|
|
||||||
NO_ICONV=YesPlease])
|
GIT_UNSTASH_FLAGS($ICONVDIR)
|
||||||
LIBS="$old_LIBS"])
|
|
||||||
AC_SUBST(NEEDS_LIBICONV)
|
AC_SUBST(NEEDS_LIBICONV)
|
||||||
AC_SUBST(NO_ICONV)
|
AC_SUBST(NO_ICONV)
|
||||||
test -n "$NEEDS_LIBICONV" && LIBS="$LIBS -liconv"
|
|
||||||
#
|
#
|
||||||
# Define NO_DEFLATE_BOUND if deflateBound is missing from zlib.
|
# Define NO_DEFLATE_BOUND if deflateBound is missing from zlib.
|
||||||
|
|
||||||
|
GIT_STASH_FLAGS($ZLIB_PATH)
|
||||||
|
|
||||||
AC_DEFUN([ZLIBTEST_SRC], [
|
AC_DEFUN([ZLIBTEST_SRC], [
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
@@ -263,7 +453,11 @@ AC_LINK_IFELSE(ZLIBTEST_SRC,
|
|||||||
[AC_MSG_RESULT([no])
|
[AC_MSG_RESULT([no])
|
||||||
NO_DEFLATE_BOUND=yes])
|
NO_DEFLATE_BOUND=yes])
|
||||||
LIBS="$old_LIBS"
|
LIBS="$old_LIBS"
|
||||||
|
|
||||||
|
GIT_UNSTASH_FLAGS($ZLIB_PATH)
|
||||||
|
|
||||||
AC_SUBST(NO_DEFLATE_BOUND)
|
AC_SUBST(NO_DEFLATE_BOUND)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Define NEEDS_SOCKET if linking with libc is not enough (SunOS,
|
# Define NEEDS_SOCKET if linking with libc is not enough (SunOS,
|
||||||
# Patrick Mauritz).
|
# Patrick Mauritz).
|
||||||
@@ -297,13 +491,18 @@ int main(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
]])
|
]])
|
||||||
|
|
||||||
|
GIT_STASH_FLAGS($ICONVDIR)
|
||||||
|
|
||||||
AC_MSG_CHECKING([for old iconv()])
|
AC_MSG_CHECKING([for old iconv()])
|
||||||
AC_COMPILE_IFELSE(OLDICONVTEST_SRC,
|
AC_COMPILE_IFELSE(OLDICONVTEST_SRC,
|
||||||
[AC_MSG_RESULT([no])],
|
[AC_MSG_RESULT([no])],
|
||||||
[AC_MSG_RESULT([yes])
|
[AC_MSG_RESULT([yes])
|
||||||
OLD_ICONV=UnfortunatelyYes])
|
OLD_ICONV=UnfortunatelyYes])
|
||||||
AC_SUBST(OLD_ICONV)
|
|
||||||
|
|
||||||
|
GIT_UNSTASH_FLAGS($ICONVDIR)
|
||||||
|
|
||||||
|
AC_SUBST(OLD_ICONV)
|
||||||
|
|
||||||
## Checks for typedefs, structures, and compiler characteristics.
|
## Checks for typedefs, structures, and compiler characteristics.
|
||||||
AC_MSG_NOTICE([CHECKS for typedefs, structures, and compiler characteristics])
|
AC_MSG_NOTICE([CHECKS for typedefs, structures, and compiler characteristics])
|
||||||
@@ -494,114 +693,65 @@ AC_SUBST(NO_MKDTEMP)
|
|||||||
#
|
#
|
||||||
# Define PTHREAD_LIBS to the linker flag used for Pthread support and define
|
# Define PTHREAD_LIBS to the linker flag used for Pthread support and define
|
||||||
# THREADED_DELTA_SEARCH if Pthreads are available.
|
# THREADED_DELTA_SEARCH if Pthreads are available.
|
||||||
AC_LANG_CONFTEST([AC_LANG_PROGRAM(
|
AC_DEFUN([PTHREADTEST_SRC], [
|
||||||
[[#include <pthread.h>]],
|
#include <pthread.h>
|
||||||
[[pthread_mutex_t test_mutex;]]
|
|
||||||
)])
|
int main(void)
|
||||||
${CC} -pthread conftest.c -o conftest.o > /dev/null 2>&1
|
{
|
||||||
if test $? -eq 0;then
|
pthread_mutex_t test_mutex;
|
||||||
PTHREAD_LIBS="-pthread"
|
return (0);
|
||||||
THREADED_DELTA_SEARCH=YesPlease
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl AC_LANG_CONFTEST([AC_LANG_PROGRAM(
|
||||||
|
dnl [[#include <pthread.h>]],
|
||||||
|
dnl [[pthread_mutex_t test_mutex;]]
|
||||||
|
dnl )])
|
||||||
|
|
||||||
|
NO_PTHREADS=UnfortunatelyYes
|
||||||
|
THREADED_DELTA_SEARCH=
|
||||||
|
PTHREAD_LIBS=
|
||||||
|
|
||||||
|
if test -n "$USER_NOPTHREAD"; then
|
||||||
|
AC_MSG_NOTICE([Skipping POSIX Threads at user request.])
|
||||||
|
# handle these separately since PTHREAD_CFLAGS could be '-lpthreads
|
||||||
|
# -D_REENTRANT' or some such.
|
||||||
|
elif test -z "$PTHREAD_CFLAGS"; then
|
||||||
|
for opt in -pthread -lpthread; do
|
||||||
|
old_CFLAGS="$CFLAGS"
|
||||||
|
CFLAGS="$opt $CFLAGS"
|
||||||
|
AC_MSG_CHECKING([Checking for POSIX Threads with '$opt'])
|
||||||
|
AC_LINK_IFELSE(PTHREADTEST_SRC,
|
||||||
|
[AC_MSG_RESULT([yes])
|
||||||
|
NO_PTHREADS=
|
||||||
|
PTHREAD_LIBS="$opt"
|
||||||
|
THREADED_DELTA_SEARCH=YesPlease
|
||||||
|
break
|
||||||
|
],
|
||||||
|
[AC_MSG_RESULT([no])])
|
||||||
|
CFLAGS="$old_CFLAGS"
|
||||||
|
done
|
||||||
else
|
else
|
||||||
${CC} -lpthread conftest.c -o conftest.o > /dev/null 2>&1
|
old_CFLAGS="$CFLAGS"
|
||||||
if test $? -eq 0;then
|
CFLAGS="$PTHREAD_CFLAGS $CFLAGS"
|
||||||
PTHREAD_LIBS="-lpthread"
|
AC_MSG_CHECKING([Checking for POSIX Threads with '$PTHREAD_CFLAGS'])
|
||||||
THREADED_DELTA_SEARCH=YesPlease
|
AC_LINK_IFELSE(PTHREADTEST_SRC,
|
||||||
else
|
[AC_MSG_RESULT([yes])
|
||||||
NO_PTHREADS=UnfortunatelyYes
|
NO_PTHREADS=
|
||||||
fi
|
PTHREAD_LIBS="$PTHREAD_CFLAGS"
|
||||||
|
THREADED_DELTA_SEARCH=YesPlease
|
||||||
|
],
|
||||||
|
[AC_MSG_RESULT([no])])
|
||||||
|
|
||||||
|
CFLAGS="$old_CFLAGS"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
CFLAGS="$old_CFLAGS"
|
||||||
|
|
||||||
AC_SUBST(PTHREAD_LIBS)
|
AC_SUBST(PTHREAD_LIBS)
|
||||||
AC_SUBST(NO_PTHREADS)
|
AC_SUBST(NO_PTHREADS)
|
||||||
AC_SUBST(THREADED_DELTA_SEARCH)
|
AC_SUBST(THREADED_DELTA_SEARCH)
|
||||||
|
|
||||||
## Site configuration (override autodetection)
|
|
||||||
## --with-PACKAGE[=ARG] and --without-PACKAGE
|
|
||||||
AC_MSG_NOTICE([CHECKS for site configuration])
|
|
||||||
#
|
|
||||||
# Define NO_SVN_TESTS if you want to skip time-consuming SVN interoperability
|
|
||||||
# tests. These tests take up a significant amount of the total test time
|
|
||||||
# but are not needed unless you plan to talk to SVN repos.
|
|
||||||
#
|
|
||||||
# Define MOZILLA_SHA1 environment variable when running make to make use of
|
|
||||||
# a bundled SHA1 routine coming from Mozilla. It is GPL'd and should be fast
|
|
||||||
# on non-x86 architectures (e.g. PowerPC), while the OpenSSL version (default
|
|
||||||
# choice) has very fast version optimized for i586.
|
|
||||||
#
|
|
||||||
# Define PPC_SHA1 environment variable when running make to make use of
|
|
||||||
# a bundled SHA1 routine optimized for PowerPC.
|
|
||||||
#
|
|
||||||
# Define ARM_SHA1 environment variable when running make to make use of
|
|
||||||
# a bundled SHA1 routine optimized for ARM.
|
|
||||||
#
|
|
||||||
# Define NO_OPENSSL environment variable if you do not have OpenSSL.
|
|
||||||
# This also implies MOZILLA_SHA1.
|
|
||||||
#
|
|
||||||
# Define OPENSSLDIR=/foo/bar if your openssl header and library files are in
|
|
||||||
# /foo/bar/include and /foo/bar/lib directories.
|
|
||||||
AC_ARG_WITH(openssl,
|
|
||||||
AS_HELP_STRING([--with-openssl],[use OpenSSL library (default is YES)])
|
|
||||||
AS_HELP_STRING([], [ARG can be prefix for openssl library and headers]),\
|
|
||||||
GIT_PARSE_WITH(openssl))
|
|
||||||
#
|
|
||||||
# Define NO_CURL if you do not have curl installed. git-http-pull and
|
|
||||||
# git-http-push are not built, and you cannot use http:// and https://
|
|
||||||
# transports.
|
|
||||||
#
|
|
||||||
# Define CURLDIR=/foo/bar if your curl header and library files are in
|
|
||||||
# /foo/bar/include and /foo/bar/lib directories.
|
|
||||||
AC_ARG_WITH(curl,
|
|
||||||
AS_HELP_STRING([--with-curl],[support http(s):// transports (default is YES)])
|
|
||||||
AS_HELP_STRING([], [ARG can be also prefix for curl library and headers]),
|
|
||||||
GIT_PARSE_WITH(curl))
|
|
||||||
#
|
|
||||||
# Define NO_EXPAT if you do not have expat installed. git-http-push is
|
|
||||||
# not built, and you cannot push using http:// and https:// transports.
|
|
||||||
#
|
|
||||||
# Define EXPATDIR=/foo/bar if your expat header and library files are in
|
|
||||||
# /foo/bar/include and /foo/bar/lib directories.
|
|
||||||
AC_ARG_WITH(expat,
|
|
||||||
AS_HELP_STRING([--with-expat],
|
|
||||||
[support git-push using http:// and https:// transports via WebDAV (default is YES)])
|
|
||||||
AS_HELP_STRING([], [ARG can be also prefix for expat library and headers]),
|
|
||||||
GIT_PARSE_WITH(expat))
|
|
||||||
#
|
|
||||||
# Define NO_FINK if you are building on Darwin/Mac OS X, have Fink
|
|
||||||
# installed in /sw, but don't want GIT to link against any libraries
|
|
||||||
# installed there. If defined you may specify your own (or Fink's)
|
|
||||||
# include directories and library directories by defining CFLAGS
|
|
||||||
# and LDFLAGS appropriately.
|
|
||||||
#
|
|
||||||
# Define NO_DARWIN_PORTS if you are building on Darwin/Mac OS X,
|
|
||||||
# have DarwinPorts installed in /opt/local, but don't want GIT to
|
|
||||||
# link against any libraries installed there. If defined you may
|
|
||||||
# specify your own (or DarwinPort's) include directories and
|
|
||||||
# library directories by defining CFLAGS and LDFLAGS appropriately.
|
|
||||||
#
|
|
||||||
# Define NO_MMAP if you want to avoid mmap.
|
|
||||||
#
|
|
||||||
# Define NO_ICONV if your libc does not properly support iconv.
|
|
||||||
AC_ARG_WITH(iconv,
|
|
||||||
AS_HELP_STRING([--without-iconv],
|
|
||||||
[if your architecture doesn't properly support iconv])
|
|
||||||
AS_HELP_STRING([--with-iconv=PATH],
|
|
||||||
[PATH is prefix for libiconv library and headers])
|
|
||||||
AS_HELP_STRING([],
|
|
||||||
[used only if you need linking with libiconv]),
|
|
||||||
GIT_PARSE_WITH(iconv))
|
|
||||||
|
|
||||||
## --enable-FEATURE[=ARG] and --disable-FEATURE
|
|
||||||
#
|
|
||||||
# Define USE_NSEC below if you want git to care about sub-second file mtimes
|
|
||||||
# and ctimes. Note that you need recent glibc (at least 2.2.4) for this, and
|
|
||||||
# it will BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely
|
|
||||||
# randomly break unless your underlying filesystem supports those sub-second
|
|
||||||
# times (my ext3 doesn't).
|
|
||||||
#
|
|
||||||
# Define USE_STDEV below if you want git to care about the underlying device
|
|
||||||
# change being considered an inode change from the update-index perspective.
|
|
||||||
|
|
||||||
|
|
||||||
## Output files
|
## Output files
|
||||||
AC_CONFIG_FILES(["${config_file}":"${config_in}":"${config_append}"])
|
AC_CONFIG_FILES(["${config_file}":"${config_in}":"${config_append}"])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
|||||||
@@ -899,7 +899,7 @@ _git_diff ()
|
|||||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
case "$cur" in
|
case "$cur" in
|
||||||
--*)
|
--*)
|
||||||
__gitcomp "--cached --pickaxe-all --pickaxe-regex
|
__gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
|
||||||
--base --ours --theirs
|
--base --ours --theirs
|
||||||
$__git_diff_common_options
|
$__git_diff_common_options
|
||||||
"
|
"
|
||||||
@@ -930,15 +930,21 @@ _git_format_patch ()
|
|||||||
{
|
{
|
||||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
case "$cur" in
|
case "$cur" in
|
||||||
|
--thread=*)
|
||||||
|
__gitcomp "
|
||||||
|
deep shallow
|
||||||
|
" "" "${cur##--thread=}"
|
||||||
|
return
|
||||||
|
;;
|
||||||
--*)
|
--*)
|
||||||
__gitcomp "
|
__gitcomp "
|
||||||
--stdout --attach --thread
|
--stdout --attach --no-attach --thread --thread=
|
||||||
--output-directory
|
--output-directory
|
||||||
--numbered --start-number
|
--numbered --start-number
|
||||||
--numbered-files
|
--numbered-files
|
||||||
--keep-subject
|
--keep-subject
|
||||||
--signoff
|
--signoff
|
||||||
--in-reply-to=
|
--in-reply-to= --cc=
|
||||||
--full-index --binary
|
--full-index --binary
|
||||||
--not --all
|
--not --all
|
||||||
--cover-letter
|
--cover-letter
|
||||||
@@ -952,6 +958,21 @@ _git_format_patch ()
|
|||||||
__git_complete_revlist
|
__git_complete_revlist
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_git_fsck ()
|
||||||
|
{
|
||||||
|
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
|
case "$cur" in
|
||||||
|
--*)
|
||||||
|
__gitcomp "
|
||||||
|
--tags --root --unreachable --cache --no-reflogs --full
|
||||||
|
--strict --verbose --lost-found
|
||||||
|
"
|
||||||
|
return
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
COMPREPLY=()
|
||||||
|
}
|
||||||
|
|
||||||
_git_gc ()
|
_git_gc ()
|
||||||
{
|
{
|
||||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
@@ -1082,7 +1103,7 @@ _git_log ()
|
|||||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
local g="$(git rev-parse --git-dir 2>/dev/null)"
|
local g="$(git rev-parse --git-dir 2>/dev/null)"
|
||||||
local merge=""
|
local merge=""
|
||||||
if [ -f $g/MERGE_HEAD ]; then
|
if [ -f "$g/MERGE_HEAD" ]; then
|
||||||
merge="--merge"
|
merge="--merge"
|
||||||
fi
|
fi
|
||||||
case "$cur" in
|
case "$cur" in
|
||||||
@@ -1249,8 +1270,8 @@ _git_send_email ()
|
|||||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
case "$cur" in
|
case "$cur" in
|
||||||
--*)
|
--*)
|
||||||
__gitcomp "--bcc --cc --cc-cmd --chain-reply-to --compose
|
__gitcomp "--annotate --bcc --cc --cc-cmd --chain-reply-to
|
||||||
--dry-run --envelope-sender --from --identity
|
--compose --dry-run --envelope-sender --from --identity
|
||||||
--in-reply-to --no-chain-reply-to --no-signed-off-by-cc
|
--in-reply-to --no-chain-reply-to --no-signed-off-by-cc
|
||||||
--no-suppress-from --no-thread --quiet
|
--no-suppress-from --no-thread --quiet
|
||||||
--signed-off-by-cc --smtp-pass --smtp-server
|
--signed-off-by-cc --smtp-pass --smtp-server
|
||||||
@@ -1516,7 +1537,7 @@ _git_config ()
|
|||||||
|
|
||||||
_git_remote ()
|
_git_remote ()
|
||||||
{
|
{
|
||||||
local subcommands="add rename rm show prune update"
|
local subcommands="add rename rm show prune update set-head"
|
||||||
local subcommand="$(__git_find_subcommand "$subcommands")"
|
local subcommand="$(__git_find_subcommand "$subcommands")"
|
||||||
if [ -z "$subcommand" ]; then
|
if [ -z "$subcommand" ]; then
|
||||||
__gitcomp "$subcommands"
|
__gitcomp "$subcommands"
|
||||||
@@ -1880,6 +1901,7 @@ _git ()
|
|||||||
diff) _git_diff ;;
|
diff) _git_diff ;;
|
||||||
fetch) _git_fetch ;;
|
fetch) _git_fetch ;;
|
||||||
format-patch) _git_format_patch ;;
|
format-patch) _git_format_patch ;;
|
||||||
|
fsck) _git_fsck ;;
|
||||||
gc) _git_gc ;;
|
gc) _git_gc ;;
|
||||||
grep) _git_grep ;;
|
grep) _git_grep ;;
|
||||||
help) _git_help ;;
|
help) _git_help ;;
|
||||||
@@ -1921,7 +1943,7 @@ _gitk ()
|
|||||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
local g="$(__gitdir)"
|
local g="$(__gitdir)"
|
||||||
local merge=""
|
local merge=""
|
||||||
if [ -f $g/MERGE_HEAD ]; then
|
if [ -f "$g/MERGE_HEAD" ]; then
|
||||||
merge="--merge"
|
merge="--merge"
|
||||||
fi
|
fi
|
||||||
case "$cur" in
|
case "$cur" in
|
||||||
|
|||||||
@@ -14,13 +14,18 @@ die "usage: import-tars *.tar.{gz,bz2,Z}\n" unless @ARGV;
|
|||||||
|
|
||||||
my $branch_name = 'import-tars';
|
my $branch_name = 'import-tars';
|
||||||
my $branch_ref = "refs/heads/$branch_name";
|
my $branch_ref = "refs/heads/$branch_name";
|
||||||
my $committer_name = 'T Ar Creator';
|
my $author_name = $ENV{'GIT_AUTHOR_NAME'} || 'T Ar Creator';
|
||||||
my $committer_email = 'tar@example.com';
|
my $author_email = $ENV{'GIT_AUTHOR_EMAIL'} || 'tar@example.com';
|
||||||
|
my $committer_name = $ENV{'GIT_COMMITTER_NAME'} || `git config --get user.name`;
|
||||||
|
my $committer_email = $ENV{'GIT_COMMITTER_EMAIL'} || `git config --get user.email`;
|
||||||
|
|
||||||
|
chomp($committer_name, $committer_email);
|
||||||
|
|
||||||
open(FI, '|-', 'git', 'fast-import', '--quiet')
|
open(FI, '|-', 'git', 'fast-import', '--quiet')
|
||||||
or die "Unable to start git fast-import: $!\n";
|
or die "Unable to start git fast-import: $!\n";
|
||||||
foreach my $tar_file (@ARGV)
|
foreach my $tar_file (@ARGV)
|
||||||
{
|
{
|
||||||
|
my $commit_time = time;
|
||||||
$tar_file =~ m,([^/]+)$,;
|
$tar_file =~ m,([^/]+)$,;
|
||||||
my $tar_name = $1;
|
my $tar_name = $1;
|
||||||
|
|
||||||
@@ -39,7 +44,7 @@ foreach my $tar_file (@ARGV)
|
|||||||
die "Unrecognized compression format: $tar_file\n";
|
die "Unrecognized compression format: $tar_file\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
my $commit_time = 0;
|
my $author_time = 0;
|
||||||
my $next_mark = 1;
|
my $next_mark = 1;
|
||||||
my $have_top_dir = 1;
|
my $have_top_dir = 1;
|
||||||
my ($top_dir, %files);
|
my ($top_dir, %files);
|
||||||
@@ -92,7 +97,7 @@ foreach my $tar_file (@ARGV)
|
|||||||
}
|
}
|
||||||
$files{$path} = [$next_mark++, $mode];
|
$files{$path} = [$next_mark++, $mode];
|
||||||
|
|
||||||
$commit_time = $mtime if $mtime > $commit_time;
|
$author_time = $mtime if $mtime > $author_time;
|
||||||
$path =~ m,^([^/]+)/,;
|
$path =~ m,^([^/]+)/,;
|
||||||
$top_dir = $1 unless $top_dir;
|
$top_dir = $1 unless $top_dir;
|
||||||
$have_top_dir = 0 if $top_dir ne $1;
|
$have_top_dir = 0 if $top_dir ne $1;
|
||||||
@@ -100,6 +105,7 @@ foreach my $tar_file (@ARGV)
|
|||||||
|
|
||||||
print FI <<EOF;
|
print FI <<EOF;
|
||||||
commit $branch_ref
|
commit $branch_ref
|
||||||
|
author $author_name <$author_email> $author_time +0000
|
||||||
committer $committer_name <$committer_email> $commit_time +0000
|
committer $committer_name <$committer_email> $commit_time +0000
|
||||||
data <<END_OF_COMMIT_MESSAGE
|
data <<END_OF_COMMIT_MESSAGE
|
||||||
Imported from $tar_file.
|
Imported from $tar_file.
|
||||||
@@ -119,7 +125,7 @@ EOF
|
|||||||
print FI <<EOF;
|
print FI <<EOF;
|
||||||
tag $tar_name
|
tag $tar_name
|
||||||
from $branch_ref
|
from $branch_ref
|
||||||
tagger $committer_name <$committer_email> $commit_time +0000
|
tagger $author_name <$author_email> $author_time +0000
|
||||||
data <<END_OF_TAG_MESSAGE
|
data <<END_OF_TAG_MESSAGE
|
||||||
Package $tar_name
|
Package $tar_name
|
||||||
END_OF_TAG_MESSAGE
|
END_OF_TAG_MESSAGE
|
||||||
|
|||||||
@@ -44,7 +44,8 @@ for zipfile in argv[1:]:
|
|||||||
common_prefix = name[:name.rfind('/') + 1]
|
common_prefix = name[:name.rfind('/') + 1]
|
||||||
else:
|
else:
|
||||||
while not name.startswith(common_prefix):
|
while not name.startswith(common_prefix):
|
||||||
common_prefix = name[:name.rfind('/') + 1]
|
last_slash = common_prefix[:-1].rfind('/') + 1
|
||||||
|
common_prefix = common_prefix[:last_slash]
|
||||||
|
|
||||||
mark[name] = ':' + str(next_mark)
|
mark[name] = ':' + str(next_mark)
|
||||||
next_mark += 1
|
next_mark += 1
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ static int check_removed(const struct cache_entry *ce, struct stat *st)
|
|||||||
return -1;
|
return -1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (has_symlink_leading_path(ce_namelen(ce), ce->name))
|
if (has_symlink_leading_path(ce->name, ce_namelen(ce)))
|
||||||
return 1;
|
return 1;
|
||||||
if (S_ISDIR(st->st_mode)) {
|
if (S_ISDIR(st->st_mode)) {
|
||||||
unsigned char sub[20];
|
unsigned char sub[20];
|
||||||
|
|||||||
@@ -205,8 +205,6 @@ void diff_no_index(struct rev_info *revs,
|
|||||||
no_index ? "--no-index" : "[--no-index]");
|
no_index ? "--no-index" : "[--no-index]");
|
||||||
|
|
||||||
diff_setup(&revs->diffopt);
|
diff_setup(&revs->diffopt);
|
||||||
if (!revs->diffopt.output_format)
|
|
||||||
revs->diffopt.output_format = DIFF_FORMAT_PATCH;
|
|
||||||
for (i = 1; i < argc - 2; ) {
|
for (i = 1; i < argc - 2; ) {
|
||||||
int j;
|
int j;
|
||||||
if (!strcmp(argv[i], "--no-index"))
|
if (!strcmp(argv[i], "--no-index"))
|
||||||
@@ -252,6 +250,8 @@ void diff_no_index(struct rev_info *revs,
|
|||||||
revs->diffopt.paths = argv + argc - 2;
|
revs->diffopt.paths = argv + argc - 2;
|
||||||
revs->diffopt.nr_paths = 2;
|
revs->diffopt.nr_paths = 2;
|
||||||
revs->diffopt.skip_stat_unmatch = 1;
|
revs->diffopt.skip_stat_unmatch = 1;
|
||||||
|
if (!revs->diffopt.output_format)
|
||||||
|
revs->diffopt.output_format = DIFF_FORMAT_PATCH;
|
||||||
|
|
||||||
DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);
|
DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);
|
||||||
DIFF_OPT_SET(&revs->diffopt, NO_INDEX);
|
DIFF_OPT_SET(&revs->diffopt, NO_INDEX);
|
||||||
|
|||||||
10
diff.c
10
diff.c
@@ -1757,7 +1757,8 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
int pos, len;
|
int pos, len;
|
||||||
|
|
||||||
/* We do not read the cache ourselves here, because the
|
/*
|
||||||
|
* We do not read the cache ourselves here, because the
|
||||||
* benchmark with my previous version that always reads cache
|
* benchmark with my previous version that always reads cache
|
||||||
* shows that it makes things worse for diff-tree comparing
|
* shows that it makes things worse for diff-tree comparing
|
||||||
* two linux-2.6 kernel trees in an already checked out work
|
* two linux-2.6 kernel trees in an already checked out work
|
||||||
@@ -1797,6 +1798,13 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int
|
|||||||
if (hashcmp(sha1, ce->sha1) || !S_ISREG(ce->ce_mode))
|
if (hashcmp(sha1, ce->sha1) || !S_ISREG(ce->ce_mode))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If ce is marked as "assume unchanged", there is no
|
||||||
|
* guarantee that work tree matches what we are looking for.
|
||||||
|
*/
|
||||||
|
if (ce->ce_flags & CE_VALID)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If ce matches the file in the work tree, we can reuse it.
|
* If ce matches the file in the work tree, we can reuse it.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -25,10 +25,12 @@ static unsigned int contains(struct diff_filespec *one,
|
|||||||
regmatch_t regmatch;
|
regmatch_t regmatch;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
|
assert(data[sz] == '\0');
|
||||||
while (*data && !regexec(regexp, data, 1, ®match, flags)) {
|
while (*data && !regexec(regexp, data, 1, ®match, flags)) {
|
||||||
flags |= REG_NOTBOL;
|
flags |= REG_NOTBOL;
|
||||||
data += regmatch.rm_so;
|
data += regmatch.rm_eo;
|
||||||
if (*data) data++;
|
if (*data && regmatch.rm_so == regmatch.rm_eo)
|
||||||
|
data++;
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
19
dir.c
19
dir.c
@@ -487,14 +487,14 @@ static enum directory_treatment treat_directory(struct dir_struct *dir,
|
|||||||
return recurse_into_directory;
|
return recurse_into_directory;
|
||||||
|
|
||||||
case index_gitdir:
|
case index_gitdir:
|
||||||
if (dir->show_other_directories)
|
if (dir->flags & DIR_SHOW_OTHER_DIRECTORIES)
|
||||||
return ignore_directory;
|
return ignore_directory;
|
||||||
return show_directory;
|
return show_directory;
|
||||||
|
|
||||||
case index_nonexistent:
|
case index_nonexistent:
|
||||||
if (dir->show_other_directories)
|
if (dir->flags & DIR_SHOW_OTHER_DIRECTORIES)
|
||||||
break;
|
break;
|
||||||
if (!dir->no_gitlinks) {
|
if (!(dir->flags & DIR_NO_GITLINKS)) {
|
||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
if (resolve_gitlink_ref(dirname, "HEAD", sha1) == 0)
|
if (resolve_gitlink_ref(dirname, "HEAD", sha1) == 0)
|
||||||
return show_directory;
|
return show_directory;
|
||||||
@@ -503,7 +503,7 @@ static enum directory_treatment treat_directory(struct dir_struct *dir,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* This is the "show_other_directories" case */
|
/* This is the "show_other_directories" case */
|
||||||
if (!dir->hide_empty_directories)
|
if (!(dir->flags & DIR_HIDE_EMPTY_DIRECTORIES))
|
||||||
return show_directory;
|
return show_directory;
|
||||||
if (!read_directory_recursive(dir, dirname, dirname, len, 1, simplify))
|
if (!read_directory_recursive(dir, dirname, dirname, len, 1, simplify))
|
||||||
return ignore_directory;
|
return ignore_directory;
|
||||||
@@ -601,7 +601,7 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
|
|||||||
|
|
||||||
dtype = DTYPE(de);
|
dtype = DTYPE(de);
|
||||||
exclude = excluded(dir, fullname, &dtype);
|
exclude = excluded(dir, fullname, &dtype);
|
||||||
if (exclude && dir->collect_ignored
|
if (exclude && (dir->flags & DIR_COLLECT_IGNORED)
|
||||||
&& in_pathspec(fullname, baselen + len, simplify))
|
&& in_pathspec(fullname, baselen + len, simplify))
|
||||||
dir_add_ignored(dir, fullname, baselen + len);
|
dir_add_ignored(dir, fullname, baselen + len);
|
||||||
|
|
||||||
@@ -609,7 +609,7 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
|
|||||||
* Excluded? If we don't explicitly want to show
|
* Excluded? If we don't explicitly want to show
|
||||||
* ignored files, ignore it
|
* ignored files, ignore it
|
||||||
*/
|
*/
|
||||||
if (exclude && !dir->show_ignored)
|
if (exclude && !(dir->flags & DIR_SHOW_IGNORED))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (dtype == DT_UNKNOWN)
|
if (dtype == DT_UNKNOWN)
|
||||||
@@ -621,7 +621,7 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
|
|||||||
* even if we don't ignore them, since the
|
* even if we don't ignore them, since the
|
||||||
* directory may contain files that we do..
|
* directory may contain files that we do..
|
||||||
*/
|
*/
|
||||||
if (!exclude && dir->show_ignored) {
|
if (!exclude && (dir->flags & DIR_SHOW_IGNORED)) {
|
||||||
if (dtype != DT_DIR)
|
if (dtype != DT_DIR)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -634,7 +634,8 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
|
|||||||
len++;
|
len++;
|
||||||
switch (treat_directory(dir, fullname, baselen + len, simplify)) {
|
switch (treat_directory(dir, fullname, baselen + len, simplify)) {
|
||||||
case show_directory:
|
case show_directory:
|
||||||
if (exclude != dir->show_ignored)
|
if (exclude != !!(dir->flags
|
||||||
|
& DIR_SHOW_IGNORED))
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
case recurse_into_directory:
|
case recurse_into_directory:
|
||||||
@@ -720,7 +721,7 @@ int read_directory(struct dir_struct *dir, const char *path, const char *base, i
|
|||||||
{
|
{
|
||||||
struct path_simplify *simplify;
|
struct path_simplify *simplify;
|
||||||
|
|
||||||
if (has_symlink_leading_path(strlen(path), path))
|
if (has_symlink_leading_path(path, strlen(path)))
|
||||||
return dir->nr;
|
return dir->nr;
|
||||||
|
|
||||||
simplify = create_simplify(pathspec);
|
simplify = create_simplify(pathspec);
|
||||||
|
|||||||
12
dir.h
12
dir.h
@@ -34,11 +34,13 @@ struct exclude_stack {
|
|||||||
struct dir_struct {
|
struct dir_struct {
|
||||||
int nr, alloc;
|
int nr, alloc;
|
||||||
int ignored_nr, ignored_alloc;
|
int ignored_nr, ignored_alloc;
|
||||||
unsigned int show_ignored:1,
|
enum {
|
||||||
show_other_directories:1,
|
DIR_SHOW_IGNORED = 1<<0,
|
||||||
hide_empty_directories:1,
|
DIR_SHOW_OTHER_DIRECTORIES = 1<<1,
|
||||||
no_gitlinks:1,
|
DIR_HIDE_EMPTY_DIRECTORIES = 1<<2,
|
||||||
collect_ignored:1;
|
DIR_NO_GITLINKS = 1<<3,
|
||||||
|
DIR_COLLECT_IGNORED = 1<<4
|
||||||
|
} flags;
|
||||||
struct dir_entry **entries;
|
struct dir_entry **entries;
|
||||||
struct dir_entry **ignored;
|
struct dir_entry **ignored;
|
||||||
|
|
||||||
|
|||||||
106
entry.c
106
entry.c
@@ -2,15 +2,19 @@
|
|||||||
#include "blob.h"
|
#include "blob.h"
|
||||||
#include "dir.h"
|
#include "dir.h"
|
||||||
|
|
||||||
static void create_directories(const char *path, const struct checkout *state)
|
static void create_directories(const char *path, int path_len,
|
||||||
|
const struct checkout *state)
|
||||||
{
|
{
|
||||||
int len = strlen(path);
|
char *buf = xmalloc(path_len + 1);
|
||||||
char *buf = xmalloc(len + 1);
|
int len = 0;
|
||||||
const char *slash = path;
|
|
||||||
|
|
||||||
while ((slash = strchr(slash+1, '/')) != NULL) {
|
while (len < path_len) {
|
||||||
len = slash - path;
|
do {
|
||||||
memcpy(buf, path, len);
|
buf[len] = path[len];
|
||||||
|
len++;
|
||||||
|
} while (len < path_len && path[len] != '/');
|
||||||
|
if (len >= path_len)
|
||||||
|
break;
|
||||||
buf[len] = 0;
|
buf[len] = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -20,7 +24,7 @@ static void create_directories(const char *path, const struct checkout *state)
|
|||||||
* we test the path components of the prefix with the
|
* we test the path components of the prefix with the
|
||||||
* stat() function instead of the lstat() function.
|
* stat() function instead of the lstat() function.
|
||||||
*/
|
*/
|
||||||
if (has_dirs_only_path(len, buf, state->base_dir_len))
|
if (has_dirs_only_path(buf, len, state->base_dir_len))
|
||||||
continue; /* ok, it is already a directory. */
|
continue; /* ok, it is already a directory. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -74,7 +78,7 @@ static int create_file(const char *path, unsigned int mode)
|
|||||||
return open(path, O_WRONLY | O_CREAT | O_EXCL, mode);
|
return open(path, O_WRONLY | O_CREAT | O_EXCL, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *read_blob_entry(struct cache_entry *ce, const char *path, unsigned long *size)
|
static void *read_blob_entry(struct cache_entry *ce, unsigned long *size)
|
||||||
{
|
{
|
||||||
enum object_type type;
|
enum object_type type;
|
||||||
void *new = read_sha1_file(ce->sha1, &type, size);
|
void *new = read_sha1_file(ce->sha1, &type, size);
|
||||||
@@ -89,36 +93,52 @@ static void *read_blob_entry(struct cache_entry *ce, const char *path, unsigned
|
|||||||
|
|
||||||
static int write_entry(struct cache_entry *ce, char *path, const struct checkout *state, int to_tempfile)
|
static int write_entry(struct cache_entry *ce, char *path, const struct checkout *state, int to_tempfile)
|
||||||
{
|
{
|
||||||
int fd;
|
unsigned int ce_mode_s_ifmt = ce->ce_mode & S_IFMT;
|
||||||
long wrote;
|
int fd, ret, fstat_done = 0;
|
||||||
|
char *new;
|
||||||
switch (ce->ce_mode & S_IFMT) {
|
struct strbuf buf = STRBUF_INIT;
|
||||||
char *new;
|
unsigned long size;
|
||||||
struct strbuf buf;
|
size_t wrote, newsize = 0;
|
||||||
unsigned long size;
|
struct stat st;
|
||||||
|
|
||||||
|
switch (ce_mode_s_ifmt) {
|
||||||
case S_IFREG:
|
case S_IFREG:
|
||||||
new = read_blob_entry(ce, path, &size);
|
case S_IFLNK:
|
||||||
|
new = read_blob_entry(ce, &size);
|
||||||
if (!new)
|
if (!new)
|
||||||
return error("git checkout-index: unable to read sha1 file of %s (%s)",
|
return error("git checkout-index: unable to read sha1 file of %s (%s)",
|
||||||
path, sha1_to_hex(ce->sha1));
|
path, sha1_to_hex(ce->sha1));
|
||||||
|
|
||||||
|
if (ce_mode_s_ifmt == S_IFLNK && has_symlinks && !to_tempfile) {
|
||||||
|
ret = symlink(new, path);
|
||||||
|
free(new);
|
||||||
|
if (ret)
|
||||||
|
return error("git checkout-index: unable to create symlink %s (%s)",
|
||||||
|
path, strerror(errno));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert from git internal format to working tree format
|
* Convert from git internal format to working tree format
|
||||||
*/
|
*/
|
||||||
strbuf_init(&buf, 0);
|
if (ce_mode_s_ifmt == S_IFREG &&
|
||||||
if (convert_to_working_tree(ce->name, new, size, &buf)) {
|
convert_to_working_tree(ce->name, new, size, &buf)) {
|
||||||
size_t newsize = 0;
|
|
||||||
free(new);
|
free(new);
|
||||||
new = strbuf_detach(&buf, &newsize);
|
new = strbuf_detach(&buf, &newsize);
|
||||||
size = newsize;
|
size = newsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (to_tempfile) {
|
if (to_tempfile) {
|
||||||
strcpy(path, ".merge_file_XXXXXX");
|
if (ce_mode_s_ifmt == S_IFREG)
|
||||||
|
strcpy(path, ".merge_file_XXXXXX");
|
||||||
|
else
|
||||||
|
strcpy(path, ".merge_link_XXXXXX");
|
||||||
fd = mkstemp(path);
|
fd = mkstemp(path);
|
||||||
} else
|
} else if (ce_mode_s_ifmt == S_IFREG) {
|
||||||
fd = create_file(path, ce->ce_mode);
|
fd = create_file(path, ce->ce_mode);
|
||||||
|
} else {
|
||||||
|
fd = create_file(path, 0666);
|
||||||
|
}
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
free(new);
|
free(new);
|
||||||
return error("git checkout-index: unable to create file %s (%s)",
|
return error("git checkout-index: unable to create file %s (%s)",
|
||||||
@@ -126,41 +146,16 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout
|
|||||||
}
|
}
|
||||||
|
|
||||||
wrote = write_in_full(fd, new, size);
|
wrote = write_in_full(fd, new, size);
|
||||||
|
/* use fstat() only when path == ce->name */
|
||||||
|
if (state->refresh_cache && !to_tempfile && !state->base_dir_len) {
|
||||||
|
fstat(fd, &st);
|
||||||
|
fstat_done = 1;
|
||||||
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
free(new);
|
free(new);
|
||||||
if (wrote != size)
|
if (wrote != size)
|
||||||
return error("git checkout-index: unable to write file %s", path);
|
return error("git checkout-index: unable to write file %s", path);
|
||||||
break;
|
break;
|
||||||
case S_IFLNK:
|
|
||||||
new = read_blob_entry(ce, path, &size);
|
|
||||||
if (!new)
|
|
||||||
return error("git checkout-index: unable to read sha1 file of %s (%s)",
|
|
||||||
path, sha1_to_hex(ce->sha1));
|
|
||||||
if (to_tempfile || !has_symlinks) {
|
|
||||||
if (to_tempfile) {
|
|
||||||
strcpy(path, ".merge_link_XXXXXX");
|
|
||||||
fd = mkstemp(path);
|
|
||||||
} else
|
|
||||||
fd = create_file(path, 0666);
|
|
||||||
if (fd < 0) {
|
|
||||||
free(new);
|
|
||||||
return error("git checkout-index: unable to create "
|
|
||||||
"file %s (%s)", path, strerror(errno));
|
|
||||||
}
|
|
||||||
wrote = write_in_full(fd, new, size);
|
|
||||||
close(fd);
|
|
||||||
free(new);
|
|
||||||
if (wrote != size)
|
|
||||||
return error("git checkout-index: unable to write file %s",
|
|
||||||
path);
|
|
||||||
} else {
|
|
||||||
wrote = symlink(new, path);
|
|
||||||
free(new);
|
|
||||||
if (wrote)
|
|
||||||
return error("git checkout-index: unable to create "
|
|
||||||
"symlink %s (%s)", path, strerror(errno));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case S_IFGITLINK:
|
case S_IFGITLINK:
|
||||||
if (to_tempfile)
|
if (to_tempfile)
|
||||||
return error("git checkout-index: cannot create temporary subproject %s", path);
|
return error("git checkout-index: cannot create temporary subproject %s", path);
|
||||||
@@ -172,8 +167,8 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (state->refresh_cache) {
|
if (state->refresh_cache) {
|
||||||
struct stat st;
|
if (!fstat_done)
|
||||||
lstat(ce->name, &st);
|
lstat(ce->name, &st);
|
||||||
fill_stat_cache_info(ce, &st);
|
fill_stat_cache_info(ce, &st);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -190,6 +185,7 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t
|
|||||||
|
|
||||||
memcpy(path, state->base_dir, len);
|
memcpy(path, state->base_dir, len);
|
||||||
strcpy(path + len, ce->name);
|
strcpy(path + len, ce->name);
|
||||||
|
len += ce_namelen(ce);
|
||||||
|
|
||||||
if (!lstat(path, &st)) {
|
if (!lstat(path, &st)) {
|
||||||
unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID);
|
unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID);
|
||||||
@@ -218,6 +214,6 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t
|
|||||||
return error("unable to unlink old '%s' (%s)", path, strerror(errno));
|
return error("unable to unlink old '%s' (%s)", path, strerror(errno));
|
||||||
} else if (state->not_new)
|
} else if (state->not_new)
|
||||||
return 0;
|
return 0;
|
||||||
create_directories(path, state);
|
create_directories(path, len, state);
|
||||||
return write_entry(ce, path, state, 0);
|
return write_entry(ce, path, state, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ enum safe_crlf safe_crlf = SAFE_CRLF_WARN;
|
|||||||
unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
|
unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
|
||||||
enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;
|
enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;
|
||||||
enum rebase_setup_type autorebase = AUTOREBASE_NEVER;
|
enum rebase_setup_type autorebase = AUTOREBASE_NEVER;
|
||||||
|
enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;
|
||||||
|
|
||||||
/* Parallel index stat data preload? */
|
/* Parallel index stat data preload? */
|
||||||
int core_preload_index = 0;
|
int core_preload_index = 0;
|
||||||
|
|||||||
11
exec_cmd.c
11
exec_cmd.c
@@ -28,9 +28,10 @@ const char *system_path(const char *path)
|
|||||||
!(prefix = strip_path_suffix(argv0_path, BINDIR)) &&
|
!(prefix = strip_path_suffix(argv0_path, BINDIR)) &&
|
||||||
!(prefix = strip_path_suffix(argv0_path, "git"))) {
|
!(prefix = strip_path_suffix(argv0_path, "git"))) {
|
||||||
prefix = PREFIX;
|
prefix = PREFIX;
|
||||||
fprintf(stderr, "RUNTIME_PREFIX requested, "
|
/*
|
||||||
"but prefix computation failed. "
|
* RUNTIME_PREFIX requested, but prefix computation failed.
|
||||||
"Using static fallback '%s'.\n", prefix);
|
* Using static fallback.
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -61,6 +62,10 @@ const char *git_extract_argv0_path(const char *argv0)
|
|||||||
void git_set_argv_exec_path(const char *exec_path)
|
void git_set_argv_exec_path(const char *exec_path)
|
||||||
{
|
{
|
||||||
argv_exec_path = exec_path;
|
argv_exec_path = exec_path;
|
||||||
|
/*
|
||||||
|
* Propagate this setting to external programs.
|
||||||
|
*/
|
||||||
|
setenv(EXEC_PATH_ENVIRONMENT, exec_path, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
(See Documentation/git-fast-import.txt for maintained documentation.)
|
||||||
Format of STDIN stream:
|
Format of STDIN stream:
|
||||||
|
|
||||||
stream ::= cmd*;
|
stream ::= cmd*;
|
||||||
@@ -18,8 +19,8 @@ Format of STDIN stream:
|
|||||||
|
|
||||||
new_commit ::= 'commit' sp ref_str lf
|
new_commit ::= 'commit' sp ref_str lf
|
||||||
mark?
|
mark?
|
||||||
('author' sp name '<' email '>' when lf)?
|
('author' sp name sp '<' email '>' sp when lf)?
|
||||||
'committer' sp name '<' email '>' when lf
|
'committer' sp name sp '<' email '>' sp when lf
|
||||||
commit_msg
|
commit_msg
|
||||||
('from' sp (ref_str | hexsha1 | sha1exp_str | idnum) lf)?
|
('from' sp (ref_str | hexsha1 | sha1exp_str | idnum) lf)?
|
||||||
('merge' sp (ref_str | hexsha1 | sha1exp_str | idnum) lf)*
|
('merge' sp (ref_str | hexsha1 | sha1exp_str | idnum) lf)*
|
||||||
@@ -43,7 +44,7 @@ Format of STDIN stream:
|
|||||||
|
|
||||||
new_tag ::= 'tag' sp tag_str lf
|
new_tag ::= 'tag' sp tag_str lf
|
||||||
'from' sp (ref_str | hexsha1 | sha1exp_str | idnum) lf
|
'from' sp (ref_str | hexsha1 | sha1exp_str | idnum) lf
|
||||||
('tagger' sp name '<' email '>' when lf)?
|
('tagger' sp name sp '<' email '>' sp when lf)?
|
||||||
tag_msg;
|
tag_msg;
|
||||||
tag_msg ::= data;
|
tag_msg ::= data;
|
||||||
|
|
||||||
|
|||||||
@@ -150,6 +150,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* General helper functions */
|
/* General helper functions */
|
||||||
|
extern void vreport(const char *prefix, const char *err, va_list params);
|
||||||
extern void usage(const char *err) NORETURN;
|
extern void usage(const char *err) NORETURN;
|
||||||
extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
|
extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
|
||||||
extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
|
extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
|
||||||
@@ -394,4 +395,18 @@ void git_qsort(void *base, size_t nmemb, size_t size,
|
|||||||
# define FORCE_DIR_SET_GID 0
|
# define FORCE_DIR_SET_GID 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef NO_NSEC
|
||||||
|
#undef USE_NSEC
|
||||||
|
#define ST_CTIME_NSEC(st) 0
|
||||||
|
#define ST_MTIME_NSEC(st) 0
|
||||||
|
#else
|
||||||
|
#ifdef USE_ST_TIMESPEC
|
||||||
|
#define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctimespec.tv_nsec))
|
||||||
|
#define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtimespec.tv_nsec))
|
||||||
|
#else
|
||||||
|
#define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctim.tv_nsec))
|
||||||
|
#define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtim.tv_nsec))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -272,10 +272,10 @@ test $commits -eq 0 && die "Found nothing to rewrite"
|
|||||||
|
|
||||||
# Rewrite the commits
|
# Rewrite the commits
|
||||||
|
|
||||||
i=0
|
git_filter_branch__commit_count=0
|
||||||
while read commit parents; do
|
while read commit parents; do
|
||||||
i=$(($i+1))
|
git_filter_branch__commit_count=$(($git_filter_branch__commit_count+1))
|
||||||
printf "\rRewrite $commit ($i/$commits)"
|
printf "\rRewrite $commit ($git_filter_branch__commit_count/$commits)"
|
||||||
|
|
||||||
case "$filter_subdir" in
|
case "$filter_subdir" in
|
||||||
"")
|
"")
|
||||||
|
|||||||
@@ -442,6 +442,30 @@ do_rest () {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# skip picking commits whose parents are unchanged
|
||||||
|
skip_unnecessary_picks () {
|
||||||
|
fd=3
|
||||||
|
while read command sha1 rest
|
||||||
|
do
|
||||||
|
# fd=3 means we skip the command
|
||||||
|
case "$fd,$command,$(git rev-parse --verify --quiet $sha1^)" in
|
||||||
|
3,pick,"$ONTO"*|3,p,"$ONTO"*)
|
||||||
|
# pick a commit whose parent is current $ONTO -> skip
|
||||||
|
ONTO=$sha1
|
||||||
|
;;
|
||||||
|
3,#*|3,,*)
|
||||||
|
# copy comments
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
fd=1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
echo "$command${sha1:+ }$sha1${rest:+ }$rest" >&$fd
|
||||||
|
done <"$TODO" >"$TODO.new" 3>>"$DONE" &&
|
||||||
|
mv -f "$TODO".new "$TODO" ||
|
||||||
|
die "Could not skip unnecessary pick commands"
|
||||||
|
}
|
||||||
|
|
||||||
# check if no other options are set
|
# check if no other options are set
|
||||||
is_standalone () {
|
is_standalone () {
|
||||||
test $# -eq 2 -a "$2" = '--' &&
|
test $# -eq 2 -a "$2" = '--' &&
|
||||||
@@ -746,6 +770,8 @@ EOF
|
|||||||
has_action "$TODO" ||
|
has_action "$TODO" ||
|
||||||
die_abort "Nothing to do"
|
die_abort "Nothing to do"
|
||||||
|
|
||||||
|
test -d "$REWRITTEN" || skip_unnecessary_picks
|
||||||
|
|
||||||
git update-ref ORIG_HEAD $HEAD
|
git update-ref ORIG_HEAD $HEAD
|
||||||
output git checkout $ONTO && do_rest
|
output git checkout $ONTO && do_rest
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -309,13 +309,17 @@ do
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
|
--committer-date-is-author-date|--ignore-date)
|
||||||
|
git_am_opt="$git_am_opt $1"
|
||||||
|
force_rebase=t
|
||||||
|
;;
|
||||||
-C*)
|
-C*)
|
||||||
git_am_opt="$git_am_opt $1"
|
git_am_opt="$git_am_opt $1"
|
||||||
;;
|
;;
|
||||||
--root)
|
--root)
|
||||||
rebase_root=t
|
rebase_root=t
|
||||||
;;
|
;;
|
||||||
-f|--f|--fo|--for|--forc|force|--force-r|--force-re|--force-reb|--force-reba|--force_rebas|--force-rebase)
|
-f|--f|--fo|--for|--forc|force|--force-r|--force-re|--force-reb|--force-reba|--force-rebas|--force-rebase)
|
||||||
force_rebase=t
|
force_rebase=t
|
||||||
;;
|
;;
|
||||||
-*)
|
-*)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user