mirror of
https://github.com/git/git.git
synced 2026-04-01 12:30:09 +02:00
Merge branch 'master' of git://repo.or.cz/alt-git
This commit is contained in:
25
COPYING
25
COPYING
@@ -22,8 +22,8 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@@ -36,7 +36,7 @@ software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
@@ -76,7 +76,7 @@ patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
@@ -131,7 +131,7 @@ above, provided that you also meet all of these conditions:
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
@@ -189,7 +189,7 @@ access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
@@ -246,7 +246,7 @@ impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
@@ -299,7 +299,7 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
@@ -324,10 +324,9 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
@@ -357,5 +356,5 @@ necessary. Here is a sample; alter the names:
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
|
||||
@@ -204,7 +204,7 @@ install-pdf: pdf
|
||||
install-html: html
|
||||
'$(SHELL_PATH_SQ)' ./install-webdoc.sh $(DESTDIR)$(htmldir)
|
||||
|
||||
../GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
|
||||
../GIT-VERSION-FILE: FORCE
|
||||
$(QUIET_SUBDIR0)../ $(QUIET_SUBDIR1) GIT-VERSION-FILE
|
||||
|
||||
-include ../GIT-VERSION-FILE
|
||||
@@ -337,4 +337,4 @@ quick-install-man:
|
||||
quick-install-html:
|
||||
'$(SHELL_PATH_SQ)' ./install-doc-quick.sh $(HTML_REF) $(DESTDIR)$(htmldir)
|
||||
|
||||
.PHONY: .FORCE-GIT-VERSION-FILE
|
||||
.PHONY: FORCE
|
||||
|
||||
@@ -44,18 +44,55 @@ Updates since v1.6.6
|
||||
|
||||
(subsystems)
|
||||
|
||||
* "git fast-import" updates; adds "option" and "feature" to detect the
|
||||
mismatch between fast-import and the frontends that produce the input
|
||||
stream.
|
||||
|
||||
(portability)
|
||||
|
||||
(performance)
|
||||
|
||||
(usability, bells and whistles)
|
||||
|
||||
* More commands learned "--quiet" and "--[no-]progress" options.
|
||||
|
||||
* Various commands given by the end user (e.g. diff.type.textconv,
|
||||
and GIT_EDITOR) can be specified with command line arguments. E.g. it
|
||||
is now possible to say "[diff "utf8doc"] textconv = nkf -w".
|
||||
|
||||
* "sparse checkout" feature allows only part of the work tree to be
|
||||
checked out.
|
||||
|
||||
* HTTP transfer can use authentication scheme other than basic
|
||||
(i.e./e.g. digest).
|
||||
|
||||
* "git checkout A...B" is a way to detach HEAD at the merge base between
|
||||
A and B.
|
||||
|
||||
* "git commit --date='<date>'" can be used to override the author date
|
||||
just like "git commit --author='<name> <email>'" can be used to
|
||||
override the author identity.
|
||||
|
||||
* "git commit --no-status" can be used to omit the listing of the index
|
||||
and the work tree status in the editor used to prepare the log message.
|
||||
|
||||
* "git fetch --all" can now be used in place of "git remote update".
|
||||
|
||||
* "git push" learned "git push origin --delete branch", a syntactic sugar
|
||||
for "git push origin :branch".
|
||||
|
||||
* "git rebase --onto A...B" means the history is replayed on top of the
|
||||
merge base between A and B.
|
||||
|
||||
* Use of "git reset --merge" has become easier when resetting away a
|
||||
conflicted mess left in the work tree.
|
||||
|
||||
* "git status" learned "-s(hort)" output format.
|
||||
|
||||
(developers)
|
||||
|
||||
* The infrastructure to build foreign SCM interface has been updated.
|
||||
|
||||
|
||||
Fixes since v1.6.6
|
||||
------------------
|
||||
@@ -65,6 +102,6 @@ release, unless otherwise noted.
|
||||
|
||||
--
|
||||
exec >/var/tmp/1
|
||||
O=v1.6.6-101-gf012d27
|
||||
O=v1.6.6-242-gf287c65
|
||||
echo O=$(git describe master)
|
||||
git shortlog --no-merges $O..master ^maint
|
||||
|
||||
@@ -98,8 +98,10 @@ commit.
|
||||
files that were modified in the same commit. This is
|
||||
useful when you reorganize your program and move code
|
||||
around across files. When this option is given twice,
|
||||
the command additionally looks for copies from all other
|
||||
files in the parent for the commit that creates the file.
|
||||
the command additionally looks for copies from other
|
||||
files in the commit that creates the file. When this
|
||||
option is given three times, the command additionally
|
||||
looks for copies from other files in any commit.
|
||||
+
|
||||
<num> is optional but it is the lower bound on the number of
|
||||
alphanumeric characters that git must detect as moving
|
||||
|
||||
@@ -716,6 +716,11 @@ color.ui::
|
||||
terminal. When more specific variables of color.* are set, they always
|
||||
take precedence over this setting. Defaults to false.
|
||||
|
||||
commit.status
|
||||
A boolean to enable/disable inclusion of status information in the
|
||||
commit message template when using an editor to prepare the commit
|
||||
message. Defaults to true.
|
||||
|
||||
commit.template::
|
||||
Specify a file to use as the template for new commit messages.
|
||||
"{tilde}/" is expanded to the value of `$HOME` and "{tilde}user/" to the
|
||||
|
||||
@@ -9,7 +9,7 @@ SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-p] [-w] [--incremental] [-L n,m]
|
||||
[-S <revs-file>] [-M] [-C] [-C] [--since=<date>]
|
||||
[-S <revs-file>] [-M] [-C] [-C] [-C] [--since=<date>]
|
||||
[<rev> | --contents <file> | --reverse <rev>] [--] <file>
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
@@ -96,13 +96,19 @@ objects from the source repository into a pack in the cloned repository.
|
||||
|
||||
--quiet::
|
||||
-q::
|
||||
Operate quietly. This flag is also passed to the `rsync'
|
||||
Operate quietly. Progress is not reported to the standard
|
||||
error stream. This flag is also passed to the `rsync'
|
||||
command when given.
|
||||
|
||||
--verbose::
|
||||
-v::
|
||||
Display the progress bar, even in case the standard output is not
|
||||
a terminal.
|
||||
Run verbosely.
|
||||
|
||||
--progress::
|
||||
Progress status is reported on the standard error stream
|
||||
by default when it is attached to a terminal, unless -q
|
||||
is specified. This flag forces progress status even if the
|
||||
standard error stream is not directed to a terminal.
|
||||
|
||||
--no-checkout::
|
||||
-n::
|
||||
|
||||
@@ -11,7 +11,8 @@ SYNOPSIS
|
||||
'git commit' [-a | --interactive] [-s] [-v] [-u<mode>] [--amend] [--dry-run]
|
||||
[(-c | -C) <commit>] [-F <file> | -m <msg>] [--reset-author]
|
||||
[--allow-empty] [--no-verify] [-e] [--author=<author>]
|
||||
[--date=<date>] [--cleanup=<mode>] [--] [[-i | -o ]<file>...]
|
||||
[--date=<date>] [--cleanup=<mode>] [--status | --no-status] [--]
|
||||
[[-i | -o ]<file>...]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@@ -224,6 +225,17 @@ specified.
|
||||
to be committed, paths with local changes that will be left
|
||||
uncommitted and paths that are untracked.
|
||||
|
||||
--status::
|
||||
Include the output of linkgit:git-status[1] in the commit
|
||||
message template when using an editor to prepare the commit
|
||||
message. Defaults to on, but can be used to override
|
||||
configuration variable commit.status.
|
||||
|
||||
--no-status::
|
||||
Do not include the output of linkgit:git-status[1] in the
|
||||
commit message template when using an editor to prepare the
|
||||
default commit message.
|
||||
|
||||
\--::
|
||||
Do not interpret any more arguments as options.
|
||||
|
||||
|
||||
@@ -75,6 +75,20 @@ OPTIONS
|
||||
set of marks. If a mark is defined to different values,
|
||||
the last file wins.
|
||||
|
||||
--relative-marks::
|
||||
After specifying --relative-marks= the paths specified
|
||||
with --import-marks= and --export-marks= are relative
|
||||
to an internal directory in the current repository.
|
||||
In git-fast-import this means that the paths are relative
|
||||
to the .git/info/fast-import directory. However, other
|
||||
importers may use a different location.
|
||||
|
||||
--no-relative-marks::
|
||||
Negates a previous --relative-marks. Allows for combining
|
||||
relative and non-relative marks by interweaving
|
||||
--(no-)-relative-marks= with the --(import|export)-marks=
|
||||
options.
|
||||
|
||||
--export-pack-edges=<file>::
|
||||
After creating a packfile, print a line of data to
|
||||
<file> listing the filename of the packfile and the last
|
||||
@@ -303,6 +317,15 @@ and control the current import process. More detailed discussion
|
||||
standard output. This command is optional and is not needed
|
||||
to perform an import.
|
||||
|
||||
`feature`::
|
||||
Require that fast-import supports the specified feature, or
|
||||
abort if it does not.
|
||||
|
||||
`option`::
|
||||
Specify any of the options listed under OPTIONS that do not
|
||||
change stream semantic to suit the frontend's needs. This
|
||||
command is optional and is not needed to perform an import.
|
||||
|
||||
`commit`
|
||||
~~~~~~~~
|
||||
Create or update a branch with a new commit, recording one logical
|
||||
@@ -846,6 +869,62 @@ Placing a `progress` command immediately after a `checkpoint` will
|
||||
inform the reader when the `checkpoint` has been completed and it
|
||||
can safely access the refs that fast-import updated.
|
||||
|
||||
`feature`
|
||||
~~~~~~~~~
|
||||
Require that fast-import supports the specified feature, or abort if
|
||||
it does not.
|
||||
|
||||
....
|
||||
'feature' SP <feature> LF
|
||||
....
|
||||
|
||||
The <feature> part of the command may be any string matching
|
||||
^[a-zA-Z][a-zA-Z-]*$ and should be understood by fast-import.
|
||||
|
||||
Feature work identical as their option counterparts with the
|
||||
exception of the import-marks feature, see below.
|
||||
|
||||
The following features are currently supported:
|
||||
|
||||
* date-format
|
||||
* import-marks
|
||||
* export-marks
|
||||
* relative-marks
|
||||
* no-relative-marks
|
||||
* force
|
||||
|
||||
The import-marks behaves differently from when it is specified as
|
||||
commandline option in that only one "feature import-marks" is allowed
|
||||
per stream. Also, any --import-marks= specified on the commandline
|
||||
will override those from the stream (if any).
|
||||
|
||||
`option`
|
||||
~~~~~~~~
|
||||
Processes the specified option so that git fast-import behaves in a
|
||||
way that suits the frontend's needs.
|
||||
Note that options specified by the frontend are overridden by any
|
||||
options the user may specify to git fast-import itself.
|
||||
|
||||
....
|
||||
'option' SP <option> LF
|
||||
....
|
||||
|
||||
The `<option>` part of the command may contain any of the options
|
||||
listed in the OPTIONS section that do not change import semantics,
|
||||
without the leading '--' and is treated in the same way.
|
||||
|
||||
Option commands must be the first commands on the input (not counting
|
||||
feature commands), to give an option command after any non-option
|
||||
command is an error.
|
||||
|
||||
The following commandline options change import semantics and may therefore
|
||||
not be passed as option:
|
||||
|
||||
* date-format
|
||||
* import-marks
|
||||
* export-marks
|
||||
* force
|
||||
|
||||
Crash Reports
|
||||
-------------
|
||||
If fast-import is supplied invalid input it will terminate with a
|
||||
|
||||
@@ -18,6 +18,11 @@ The program supports clients fetching using both the smart HTTP protcol
|
||||
and the backwards-compatible dumb HTTP protocol, as well as clients
|
||||
pushing using the smart HTTP protocol.
|
||||
|
||||
It verifies that the directory has the magic file
|
||||
"git-daemon-export-ok", and it will refuse to export any git directory
|
||||
that hasn't explicitly been marked for export this way (unless the
|
||||
GIT_HTTP_EXPORT_ALL environmental variable is set).
|
||||
|
||||
By default, only the `upload-pack` service is enabled, which serves
|
||||
'git-fetch-pack' and 'git-ls-remote' clients, which are invoked from
|
||||
'git-fetch', 'git-pull', and 'git-clone'. If the client is authenticated,
|
||||
@@ -70,6 +75,7 @@ Apache 2.x::
|
||||
+
|
||||
----------------------------------------------------------------
|
||||
SetEnv GIT_PROJECT_ROOT /var/www/git
|
||||
SetEnv GIT_HTTP_EXPORT_ALL
|
||||
ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
|
||||
----------------------------------------------------------------
|
||||
+
|
||||
@@ -157,6 +163,10 @@ by the invoking web server, including:
|
||||
* QUERY_STRING
|
||||
* REQUEST_METHOD
|
||||
|
||||
The GIT_HTTP_EXPORT_ALL environmental variable may be passed to
|
||||
'git-http-backend' to bypass the check for the "git-daemon-export-ok"
|
||||
file in each repository before allowing export of that repository.
|
||||
|
||||
The backend process sets GIT_COMMITTER_NAME to '$REMOTE_USER' and
|
||||
GIT_COMMITTER_EMAIL to '$\{REMOTE_USER}@http.$\{REMOTE_ADDR\}',
|
||||
ensuring that any reflogs created by 'git-receive-pack' contain some
|
||||
|
||||
56
Makefile
56
Makefile
@@ -222,7 +222,7 @@ all::
|
||||
# DEFAULT_EDITOR='$GIT_FALLBACK_EDITOR',
|
||||
# DEFAULT_EDITOR='"C:\Program Files\Vim\gvim.exe" --nofork'
|
||||
|
||||
GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
|
||||
GIT-VERSION-FILE: FORCE
|
||||
@$(SHELL_PATH) ./GIT-VERSION-GEN
|
||||
-include GIT-VERSION-FILE
|
||||
|
||||
@@ -1486,20 +1486,19 @@ shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell
|
||||
strip: $(PROGRAMS) git$X
|
||||
$(STRIP) $(STRIP_OPTS) $(PROGRAMS) git$X
|
||||
|
||||
git.o: git.c common-cmds.h GIT-CFLAGS
|
||||
$(QUIET_CC)$(CC) -DGIT_VERSION='"$(GIT_VERSION)"' \
|
||||
'-DGIT_HTML_PATH="$(htmldir_SQ)"' \
|
||||
$(ALL_CFLAGS) -o $@ -c $(filter %.c,$^)
|
||||
git.o: common-cmds.h
|
||||
git.s git.o: ALL_CFLAGS += -DGIT_VERSION='"$(GIT_VERSION)"' \
|
||||
'-DGIT_HTML_PATH="$(htmldir_SQ)"'
|
||||
|
||||
git$X: git.o $(BUILTIN_OBJS) $(GITLIBS)
|
||||
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ git.o \
|
||||
$(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
|
||||
|
||||
builtin-help.o: builtin-help.c common-cmds.h GIT-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \
|
||||
'-DGIT_HTML_PATH="$(htmldir_SQ)"' \
|
||||
'-DGIT_MAN_PATH="$(mandir_SQ)"' \
|
||||
'-DGIT_INFO_PATH="$(infodir_SQ)"' $<
|
||||
builtin-help.o: common-cmds.h
|
||||
builtin-help.s builtin-help.o: ALL_CFLAGS += \
|
||||
'-DGIT_HTML_PATH="$(htmldir_SQ)"' \
|
||||
'-DGIT_MAN_PATH="$(mandir_SQ)"' \
|
||||
'-DGIT_INFO_PATH="$(infodir_SQ)"'
|
||||
|
||||
$(BUILT_INS): git$X
|
||||
$(QUIET_BUILT_IN)$(RM) $@ && \
|
||||
@@ -1652,30 +1651,26 @@ git.o git.spec \
|
||||
|
||||
%.o: %.c GIT-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $<
|
||||
%.s: %.c GIT-CFLAGS
|
||||
%.s: %.c GIT-CFLAGS FORCE
|
||||
$(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $<
|
||||
%.o: %.S GIT-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $<
|
||||
|
||||
exec_cmd.o: exec_cmd.c GIT-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \
|
||||
'-DGIT_EXEC_PATH="$(gitexecdir_SQ)"' \
|
||||
'-DBINDIR="$(bindir_relative_SQ)"' \
|
||||
'-DPREFIX="$(prefix_SQ)"' \
|
||||
$<
|
||||
exec_cmd.s exec_cmd.o: ALL_CFLAGS += \
|
||||
'-DGIT_EXEC_PATH="$(gitexecdir_SQ)"' \
|
||||
'-DBINDIR="$(bindir_relative_SQ)"' \
|
||||
'-DPREFIX="$(prefix_SQ)"'
|
||||
|
||||
builtin-init-db.o: builtin-init-db.c GIT-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"' $<
|
||||
builtin-init-db.s builtin-init-db.o: ALL_CFLAGS += \
|
||||
-DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"'
|
||||
|
||||
config.o: config.c GIT-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DETC_GITCONFIG='"$(ETC_GITCONFIG_SQ)"' $<
|
||||
config.s config.o: ALL_CFLAGS += -DETC_GITCONFIG='"$(ETC_GITCONFIG_SQ)"'
|
||||
|
||||
http.o: http.c GIT-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DGIT_USER_AGENT='"git/$(GIT_VERSION)"' $<
|
||||
http.s http.o: ALL_CFLAGS += -DGIT_USER_AGENT='"git/$(GIT_VERSION)"'
|
||||
|
||||
ifdef NO_EXPAT
|
||||
http-walker.o: http-walker.c http.h GIT-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DNO_EXPAT $<
|
||||
http-walker.o: http.h
|
||||
http-walker.s http-walker.o: ALL_CFLAGS += -DNO_EXPAT
|
||||
endif
|
||||
|
||||
git-%$X: %.o $(GITLIBS)
|
||||
@@ -1753,7 +1748,7 @@ cscope:
|
||||
TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\
|
||||
$(bindir_SQ):$(gitexecdir_SQ):$(template_dir_SQ):$(prefix_SQ)
|
||||
|
||||
GIT-CFLAGS: .FORCE-GIT-CFLAGS
|
||||
GIT-CFLAGS: FORCE
|
||||
@FLAGS='$(TRACK_CFLAGS)'; \
|
||||
if test x"$$FLAGS" != x"`cat GIT-CFLAGS 2>/dev/null`" ; then \
|
||||
echo 1>&2 " * new build flags or prefix"; \
|
||||
@@ -1763,7 +1758,7 @@ GIT-CFLAGS: .FORCE-GIT-CFLAGS
|
||||
# We need to apply sq twice, once to protect from the shell
|
||||
# that runs GIT-BUILD-OPTIONS, and then again to protect it
|
||||
# and the first level quoting from the shell that runs "echo".
|
||||
GIT-BUILD-OPTIONS: .FORCE-GIT-BUILD-OPTIONS
|
||||
GIT-BUILD-OPTIONS: FORCE
|
||||
@echo SHELL_PATH=\''$(subst ','\'',$(SHELL_PATH_SQ))'\' >$@
|
||||
@echo PERL_PATH=\''$(subst ','\'',$(PERL_PATH_SQ))'\' >>$@
|
||||
@echo TAR=\''$(subst ','\'',$(subst ','\'',$(TAR)))'\' >>$@
|
||||
@@ -1775,14 +1770,12 @@ GIT-BUILD-OPTIONS: .FORCE-GIT-BUILD-OPTIONS
|
||||
ifndef NO_TCLTK
|
||||
TRACK_VARS = $(subst ','\'',-DTCLTK_PATH='$(TCLTK_PATH_SQ)')
|
||||
|
||||
GIT-GUI-VARS: .FORCE-GIT-GUI-VARS
|
||||
GIT-GUI-VARS: FORCE
|
||||
@VARS='$(TRACK_VARS)'; \
|
||||
if test x"$$VARS" != x"`cat $@ 2>/dev/null`" ; then \
|
||||
echo 1>&2 " * new Tcl/Tk interpreter location"; \
|
||||
echo "$$VARS" >$@; \
|
||||
fi
|
||||
|
||||
.PHONY: .FORCE-GIT-GUI-VARS
|
||||
endif
|
||||
|
||||
### Testing rules
|
||||
@@ -2024,8 +2017,7 @@ endif
|
||||
|
||||
.PHONY: all install clean strip
|
||||
.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
|
||||
.PHONY: .FORCE-GIT-VERSION-FILE TAGS tags cscope .FORCE-GIT-CFLAGS
|
||||
.PHONY: .FORCE-GIT-BUILD-OPTIONS
|
||||
.PHONY: FORCE TAGS tags cscope
|
||||
|
||||
### Check documentation
|
||||
#
|
||||
|
||||
@@ -167,7 +167,7 @@ static int checkout_merged(int pos, struct checkout *state)
|
||||
fill_mm(active_cache[pos+2]->sha1, &theirs);
|
||||
|
||||
status = ll_merge(&result_buf, path, &ancestor,
|
||||
&ours, "ours", &theirs, "theirs", 1);
|
||||
&ours, "ours", &theirs, "theirs", 0);
|
||||
free(ancestor.ptr);
|
||||
free(ours.ptr);
|
||||
free(theirs.ptr);
|
||||
|
||||
@@ -44,10 +44,13 @@ static char *option_origin = NULL;
|
||||
static char *option_branch = NULL;
|
||||
static char *option_upload_pack = "git-upload-pack";
|
||||
static int option_verbose;
|
||||
static int option_progress;
|
||||
|
||||
static struct option builtin_clone_options[] = {
|
||||
OPT__QUIET(&option_quiet),
|
||||
OPT__VERBOSE(&option_verbose),
|
||||
OPT_BOOLEAN(0, "progress", &option_progress,
|
||||
"force progress reporting"),
|
||||
OPT_BOOLEAN('n', "no-checkout", &option_no_checkout,
|
||||
"don't create a checkout"),
|
||||
OPT_BOOLEAN(0, "bare", &option_bare, "create a bare repository"),
|
||||
@@ -526,6 +529,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
if (option_quiet)
|
||||
transport->verbose = -1;
|
||||
else if (option_verbose)
|
||||
transport->verbose = 1;
|
||||
|
||||
if (option_progress)
|
||||
transport->progress = 1;
|
||||
|
||||
if (option_upload_pack)
|
||||
|
||||
@@ -68,7 +68,7 @@ static enum {
|
||||
} cleanup_mode;
|
||||
static char *cleanup_arg;
|
||||
|
||||
static int use_editor = 1, initial_commit, in_merge;
|
||||
static int use_editor = 1, initial_commit, in_merge, include_status = 1;
|
||||
static const char *only_include_assumed;
|
||||
static struct strbuf message;
|
||||
|
||||
@@ -107,6 +107,7 @@ static struct option builtin_commit_options[] = {
|
||||
OPT_FILENAME('t', "template", &template_file, "use specified template file"),
|
||||
OPT_BOOLEAN('e', "edit", &edit_flag, "force edit of commit"),
|
||||
OPT_STRING(0, "cleanup", &cleanup_arg, "default", "how to strip spaces and #comments from message"),
|
||||
OPT_BOOLEAN(0, "status", &include_status, "include status in commit message template"),
|
||||
/* end commit message options */
|
||||
|
||||
OPT_GROUP("Commit contents options"),
|
||||
@@ -590,7 +591,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
|
||||
|
||||
/* This checks if committer ident is explicitly given */
|
||||
git_committer_info(0);
|
||||
if (use_editor) {
|
||||
if (use_editor && include_status) {
|
||||
char *author_ident;
|
||||
const char *committer_ident;
|
||||
|
||||
@@ -1105,6 +1106,10 @@ static int git_commit_config(const char *k, const char *v, void *cb)
|
||||
|
||||
if (!strcmp(k, "commit.template"))
|
||||
return git_config_pathname(&template_file, k, v);
|
||||
if (!strcmp(k, "commit.status")) {
|
||||
include_status = git_config_bool(k, v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return git_status_config(k, v, s);
|
||||
}
|
||||
|
||||
@@ -249,10 +249,11 @@ static int filter_buffer(int fd, void *data)
|
||||
struct child_process child_process;
|
||||
struct filter_params *params = (struct filter_params *)data;
|
||||
int write_err, status;
|
||||
const char *argv[] = { "sh", "-c", params->cmd, NULL };
|
||||
const char *argv[] = { params->cmd, NULL };
|
||||
|
||||
memset(&child_process, 0, sizeof(child_process));
|
||||
child_process.argv = argv;
|
||||
child_process.use_shell = 1;
|
||||
child_process.in = -1;
|
||||
child_process.out = fd;
|
||||
|
||||
|
||||
3
diff.c
3
diff.c
@@ -2294,7 +2294,7 @@ static void run_external_diff(const char *pgm,
|
||||
}
|
||||
*arg = NULL;
|
||||
fflush(NULL);
|
||||
retval = run_command_v_opt(spawn_arg, 0);
|
||||
retval = run_command_v_opt(spawn_arg, RUN_USING_SHELL);
|
||||
remove_tempfile();
|
||||
if (retval) {
|
||||
fprintf(stderr, "external diff died, stopping at %s.\n", name);
|
||||
@@ -3818,6 +3818,7 @@ static char *run_textconv(const char *pgm, struct diff_filespec *spec,
|
||||
*arg = NULL;
|
||||
|
||||
memset(&child, 0, sizeof(child));
|
||||
child.use_shell = 1;
|
||||
child.argv = argv;
|
||||
child.out = -1;
|
||||
if (start_command(&child) != 0 ||
|
||||
|
||||
21
editor.c
21
editor.c
@@ -36,26 +36,9 @@ int launch_editor(const char *path, struct strbuf *buffer, const char *const *en
|
||||
return error("Terminal is dumb, but EDITOR unset");
|
||||
|
||||
if (strcmp(editor, ":")) {
|
||||
size_t len = strlen(editor);
|
||||
int i = 0;
|
||||
int failed;
|
||||
const char *args[6];
|
||||
struct strbuf arg0 = STRBUF_INIT;
|
||||
const char *args[] = { editor, path, NULL };
|
||||
|
||||
if (strcspn(editor, "|&;<>()$`\\\"' \t\n*?[#~=%") != len) {
|
||||
/* there are specials */
|
||||
strbuf_addf(&arg0, "%s \"$@\"", editor);
|
||||
args[i++] = "sh";
|
||||
args[i++] = "-c";
|
||||
args[i++] = arg0.buf;
|
||||
}
|
||||
args[i++] = editor;
|
||||
args[i++] = path;
|
||||
args[i] = NULL;
|
||||
|
||||
failed = run_command_v_opt_cd_env(args, 0, NULL, env);
|
||||
strbuf_release(&arg0);
|
||||
if (failed)
|
||||
if (run_command_v_opt_cd_env(args, RUN_USING_SHELL, NULL, env))
|
||||
return error("There was a problem with the editor '%s'.",
|
||||
editor);
|
||||
}
|
||||
|
||||
317
fast-import.c
317
fast-import.c
@@ -295,6 +295,9 @@ static unsigned long branch_count;
|
||||
static unsigned long branch_load_count;
|
||||
static int failure;
|
||||
static FILE *pack_edges;
|
||||
static unsigned int show_stats = 1;
|
||||
static int global_argc;
|
||||
static const char **global_argv;
|
||||
|
||||
/* Memory pools */
|
||||
static size_t mem_pool_alloc = 2*1024*1024 - sizeof(struct mem_pool);
|
||||
@@ -317,7 +320,10 @@ static unsigned int object_entry_alloc = 5000;
|
||||
static struct object_entry_pool *blocks;
|
||||
static struct object_entry *object_table[1 << 16];
|
||||
static struct mark_set *marks;
|
||||
static const char *mark_file;
|
||||
static const char *export_marks_file;
|
||||
static const char *import_marks_file;
|
||||
static int import_marks_file_from_stream;
|
||||
static int relative_marks_paths;
|
||||
|
||||
/* Our last blob */
|
||||
static struct last_object last_blob = { STRBUF_INIT, 0, 0, 0 };
|
||||
@@ -351,6 +357,9 @@ static struct recent_command *rc_free;
|
||||
static unsigned int cmd_save = 100;
|
||||
static uintmax_t next_mark;
|
||||
static struct strbuf new_data = STRBUF_INIT;
|
||||
static int seen_data_command;
|
||||
|
||||
static void parse_argv(void);
|
||||
|
||||
static void write_branch_report(FILE *rpt, struct branch *b)
|
||||
{
|
||||
@@ -454,8 +463,8 @@ static void write_crash_report(const char *err)
|
||||
fputc('\n', rpt);
|
||||
fputs("Marks\n", rpt);
|
||||
fputs("-----\n", rpt);
|
||||
if (mark_file)
|
||||
fprintf(rpt, " exported to %s\n", mark_file);
|
||||
if (export_marks_file)
|
||||
fprintf(rpt, " exported to %s\n", export_marks_file);
|
||||
else
|
||||
dump_marks_helper(rpt, 0, marks);
|
||||
|
||||
@@ -1602,13 +1611,13 @@ static void dump_marks(void)
|
||||
int mark_fd;
|
||||
FILE *f;
|
||||
|
||||
if (!mark_file)
|
||||
if (!export_marks_file)
|
||||
return;
|
||||
|
||||
mark_fd = hold_lock_file_for_update(&mark_lock, mark_file, 0);
|
||||
mark_fd = hold_lock_file_for_update(&mark_lock, export_marks_file, 0);
|
||||
if (mark_fd < 0) {
|
||||
failure |= error("Unable to write marks file %s: %s",
|
||||
mark_file, strerror(errno));
|
||||
export_marks_file, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1617,7 +1626,7 @@ static void dump_marks(void)
|
||||
int saved_errno = errno;
|
||||
rollback_lock_file(&mark_lock);
|
||||
failure |= error("Unable to write marks file %s: %s",
|
||||
mark_file, strerror(saved_errno));
|
||||
export_marks_file, strerror(saved_errno));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1633,7 +1642,7 @@ static void dump_marks(void)
|
||||
int saved_errno = errno;
|
||||
rollback_lock_file(&mark_lock);
|
||||
failure |= error("Unable to write marks file %s: %s",
|
||||
mark_file, strerror(saved_errno));
|
||||
export_marks_file, strerror(saved_errno));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1641,11 +1650,47 @@ static void dump_marks(void)
|
||||
int saved_errno = errno;
|
||||
rollback_lock_file(&mark_lock);
|
||||
failure |= error("Unable to commit marks file %s: %s",
|
||||
mark_file, strerror(saved_errno));
|
||||
export_marks_file, strerror(saved_errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void read_marks(void)
|
||||
{
|
||||
char line[512];
|
||||
FILE *f = fopen(import_marks_file, "r");
|
||||
if (!f)
|
||||
die_errno("cannot read '%s'", import_marks_file);
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
uintmax_t mark;
|
||||
char *end;
|
||||
unsigned char sha1[20];
|
||||
struct object_entry *e;
|
||||
|
||||
end = strchr(line, '\n');
|
||||
if (line[0] != ':' || !end)
|
||||
die("corrupt mark line: %s", line);
|
||||
*end = 0;
|
||||
mark = strtoumax(line + 1, &end, 10);
|
||||
if (!mark || end == line + 1
|
||||
|| *end != ' ' || get_sha1(end + 1, sha1))
|
||||
die("corrupt mark line: %s", line);
|
||||
e = find_object(sha1);
|
||||
if (!e) {
|
||||
enum object_type type = sha1_object_info(sha1, NULL);
|
||||
if (type < 0)
|
||||
die("object not found: %s", sha1_to_hex(sha1));
|
||||
e = insert_object(sha1);
|
||||
e->type = type;
|
||||
e->pack_id = MAX_PACK_ID;
|
||||
e->offset = 1; /* just not zero! */
|
||||
}
|
||||
insert_mark(mark, e);
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
|
||||
static int read_next_command(void)
|
||||
{
|
||||
static int stdin_eof = 0;
|
||||
@@ -1666,6 +1711,12 @@ static int read_next_command(void)
|
||||
if (stdin_eof)
|
||||
return EOF;
|
||||
|
||||
if (!seen_data_command
|
||||
&& prefixcmp(command_buf.buf, "feature ")
|
||||
&& prefixcmp(command_buf.buf, "option ")) {
|
||||
parse_argv();
|
||||
}
|
||||
|
||||
rc = rc_free;
|
||||
if (rc)
|
||||
rc_free = rc->next;
|
||||
@@ -2420,39 +2471,140 @@ static void parse_progress(void)
|
||||
skip_optional_lf();
|
||||
}
|
||||
|
||||
static void import_marks(const char *input_file)
|
||||
static char* make_fast_import_path(const char *path)
|
||||
{
|
||||
char line[512];
|
||||
FILE *f = fopen(input_file, "r");
|
||||
if (!f)
|
||||
die_errno("cannot read '%s'", input_file);
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
uintmax_t mark;
|
||||
char *end;
|
||||
unsigned char sha1[20];
|
||||
struct object_entry *e;
|
||||
struct strbuf abs_path = STRBUF_INIT;
|
||||
|
||||
end = strchr(line, '\n');
|
||||
if (line[0] != ':' || !end)
|
||||
die("corrupt mark line: %s", line);
|
||||
*end = 0;
|
||||
mark = strtoumax(line + 1, &end, 10);
|
||||
if (!mark || end == line + 1
|
||||
|| *end != ' ' || get_sha1(end + 1, sha1))
|
||||
die("corrupt mark line: %s", line);
|
||||
e = find_object(sha1);
|
||||
if (!e) {
|
||||
enum object_type type = sha1_object_info(sha1, NULL);
|
||||
if (type < 0)
|
||||
die("object not found: %s", sha1_to_hex(sha1));
|
||||
e = insert_object(sha1);
|
||||
e->type = type;
|
||||
e->pack_id = MAX_PACK_ID;
|
||||
e->offset = 1; /* just not zero! */
|
||||
}
|
||||
insert_mark(mark, e);
|
||||
if (!relative_marks_paths || is_absolute_path(path))
|
||||
return xstrdup(path);
|
||||
strbuf_addf(&abs_path, "%s/info/fast-import/%s", get_git_dir(), path);
|
||||
return strbuf_detach(&abs_path, NULL);
|
||||
}
|
||||
|
||||
static void option_import_marks(const char *marks, int from_stream)
|
||||
{
|
||||
if (import_marks_file) {
|
||||
if (from_stream)
|
||||
die("Only one import-marks command allowed per stream");
|
||||
|
||||
/* read previous mark file */
|
||||
if(!import_marks_file_from_stream)
|
||||
read_marks();
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
import_marks_file = make_fast_import_path(marks);
|
||||
import_marks_file_from_stream = from_stream;
|
||||
}
|
||||
|
||||
static void option_date_format(const char *fmt)
|
||||
{
|
||||
if (!strcmp(fmt, "raw"))
|
||||
whenspec = WHENSPEC_RAW;
|
||||
else if (!strcmp(fmt, "rfc2822"))
|
||||
whenspec = WHENSPEC_RFC2822;
|
||||
else if (!strcmp(fmt, "now"))
|
||||
whenspec = WHENSPEC_NOW;
|
||||
else
|
||||
die("unknown --date-format argument %s", fmt);
|
||||
}
|
||||
|
||||
static void option_max_pack_size(const char *packsize)
|
||||
{
|
||||
max_packsize = strtoumax(packsize, NULL, 0) * 1024 * 1024;
|
||||
}
|
||||
|
||||
static void option_depth(const char *depth)
|
||||
{
|
||||
max_depth = strtoul(depth, NULL, 0);
|
||||
if (max_depth > MAX_DEPTH)
|
||||
die("--depth cannot exceed %u", MAX_DEPTH);
|
||||
}
|
||||
|
||||
static void option_active_branches(const char *branches)
|
||||
{
|
||||
max_active_branches = strtoul(branches, NULL, 0);
|
||||
}
|
||||
|
||||
static void option_export_marks(const char *marks)
|
||||
{
|
||||
export_marks_file = make_fast_import_path(marks);
|
||||
}
|
||||
|
||||
static void option_export_pack_edges(const char *edges)
|
||||
{
|
||||
if (pack_edges)
|
||||
fclose(pack_edges);
|
||||
pack_edges = fopen(edges, "a");
|
||||
if (!pack_edges)
|
||||
die_errno("Cannot open '%s'", edges);
|
||||
}
|
||||
|
||||
static int parse_one_option(const char *option)
|
||||
{
|
||||
if (!prefixcmp(option, "max-pack-size=")) {
|
||||
option_max_pack_size(option + 14);
|
||||
} else if (!prefixcmp(option, "depth=")) {
|
||||
option_depth(option + 6);
|
||||
} else if (!prefixcmp(option, "active-branches=")) {
|
||||
option_active_branches(option + 16);
|
||||
} else if (!prefixcmp(option, "export-pack-edges=")) {
|
||||
option_export_pack_edges(option + 18);
|
||||
} else if (!prefixcmp(option, "quiet")) {
|
||||
show_stats = 0;
|
||||
} else if (!prefixcmp(option, "stats")) {
|
||||
show_stats = 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int parse_one_feature(const char *feature, int from_stream)
|
||||
{
|
||||
if (!prefixcmp(feature, "date-format=")) {
|
||||
option_date_format(feature + 12);
|
||||
} else if (!prefixcmp(feature, "import-marks=")) {
|
||||
option_import_marks(feature + 13, from_stream);
|
||||
} else if (!prefixcmp(feature, "export-marks=")) {
|
||||
option_export_marks(feature + 13);
|
||||
} else if (!prefixcmp(feature, "relative-marks")) {
|
||||
relative_marks_paths = 1;
|
||||
} else if (!prefixcmp(feature, "no-relative-marks")) {
|
||||
relative_marks_paths = 0;
|
||||
} else if (!prefixcmp(feature, "force")) {
|
||||
force_update = 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void parse_feature(void)
|
||||
{
|
||||
char *feature = command_buf.buf + 8;
|
||||
|
||||
if (seen_data_command)
|
||||
die("Got feature command '%s' after data command", feature);
|
||||
|
||||
if (parse_one_feature(feature, 1))
|
||||
return;
|
||||
|
||||
die("This version of fast-import does not support feature %s.", feature);
|
||||
}
|
||||
|
||||
static void parse_option(void)
|
||||
{
|
||||
char *option = command_buf.buf + 11;
|
||||
|
||||
if (seen_data_command)
|
||||
die("Got option command '%s' after data command", option);
|
||||
|
||||
if (parse_one_option(option))
|
||||
return;
|
||||
|
||||
die("This version of fast-import does not support option: %s", option);
|
||||
}
|
||||
|
||||
static int git_pack_config(const char *k, const char *v, void *cb)
|
||||
@@ -2479,9 +2631,35 @@ static int git_pack_config(const char *k, const char *v, void *cb)
|
||||
static const char fast_import_usage[] =
|
||||
"git fast-import [--date-format=f] [--max-pack-size=n] [--depth=n] [--active-branches=n] [--export-marks=marks.file]";
|
||||
|
||||
static void parse_argv(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 1; i < global_argc; i++) {
|
||||
const char *a = global_argv[i];
|
||||
|
||||
if (*a != '-' || !strcmp(a, "--"))
|
||||
break;
|
||||
|
||||
if (parse_one_option(a + 2))
|
||||
continue;
|
||||
|
||||
if (parse_one_feature(a + 2, 0))
|
||||
continue;
|
||||
|
||||
die("unknown option %s", a);
|
||||
}
|
||||
if (i != global_argc)
|
||||
usage(fast_import_usage);
|
||||
|
||||
seen_data_command = 1;
|
||||
if (import_marks_file)
|
||||
read_marks();
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
unsigned int i, show_stats = 1;
|
||||
unsigned int i;
|
||||
|
||||
git_extract_argv0_path(argv[0]);
|
||||
|
||||
@@ -2500,52 +2678,8 @@ int main(int argc, const char **argv)
|
||||
avail_tree_table = xcalloc(avail_tree_table_sz, sizeof(struct avail_tree_content*));
|
||||
marks = pool_calloc(1, sizeof(struct mark_set));
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
const char *a = argv[i];
|
||||
|
||||
if (*a != '-' || !strcmp(a, "--"))
|
||||
break;
|
||||
else if (!prefixcmp(a, "--date-format=")) {
|
||||
const char *fmt = a + 14;
|
||||
if (!strcmp(fmt, "raw"))
|
||||
whenspec = WHENSPEC_RAW;
|
||||
else if (!strcmp(fmt, "rfc2822"))
|
||||
whenspec = WHENSPEC_RFC2822;
|
||||
else if (!strcmp(fmt, "now"))
|
||||
whenspec = WHENSPEC_NOW;
|
||||
else
|
||||
die("unknown --date-format argument %s", fmt);
|
||||
}
|
||||
else if (!prefixcmp(a, "--max-pack-size="))
|
||||
max_packsize = strtoumax(a + 16, NULL, 0) * 1024 * 1024;
|
||||
else if (!prefixcmp(a, "--depth=")) {
|
||||
max_depth = strtoul(a + 8, NULL, 0);
|
||||
if (max_depth > MAX_DEPTH)
|
||||
die("--depth cannot exceed %u", MAX_DEPTH);
|
||||
}
|
||||
else if (!prefixcmp(a, "--active-branches="))
|
||||
max_active_branches = strtoul(a + 18, NULL, 0);
|
||||
else if (!prefixcmp(a, "--import-marks="))
|
||||
import_marks(a + 15);
|
||||
else if (!prefixcmp(a, "--export-marks="))
|
||||
mark_file = a + 15;
|
||||
else if (!prefixcmp(a, "--export-pack-edges=")) {
|
||||
if (pack_edges)
|
||||
fclose(pack_edges);
|
||||
pack_edges = fopen(a + 20, "a");
|
||||
if (!pack_edges)
|
||||
die_errno("Cannot open '%s'", a + 20);
|
||||
} else if (!strcmp(a, "--force"))
|
||||
force_update = 1;
|
||||
else if (!strcmp(a, "--quiet"))
|
||||
show_stats = 0;
|
||||
else if (!strcmp(a, "--stats"))
|
||||
show_stats = 1;
|
||||
else
|
||||
die("unknown option %s", a);
|
||||
}
|
||||
if (i != argc)
|
||||
usage(fast_import_usage);
|
||||
global_argc = argc;
|
||||
global_argv = argv;
|
||||
|
||||
rc_free = pool_alloc(cmd_save * sizeof(*rc_free));
|
||||
for (i = 0; i < (cmd_save - 1); i++)
|
||||
@@ -2568,9 +2702,20 @@ int main(int argc, const char **argv)
|
||||
parse_checkpoint();
|
||||
else if (!prefixcmp(command_buf.buf, "progress "))
|
||||
parse_progress();
|
||||
else if (!prefixcmp(command_buf.buf, "feature "))
|
||||
parse_feature();
|
||||
else if (!prefixcmp(command_buf.buf, "option git "))
|
||||
parse_option();
|
||||
else if (!prefixcmp(command_buf.buf, "option "))
|
||||
/* ignore non-git options*/;
|
||||
else
|
||||
die("Unsupported command: %s", command_buf.buf);
|
||||
}
|
||||
|
||||
/* argv hasn't been parsed yet, do so */
|
||||
if (!seen_data_command)
|
||||
parse_argv();
|
||||
|
||||
end_packfile();
|
||||
|
||||
dump_branches();
|
||||
|
||||
@@ -648,6 +648,9 @@ int main(int argc, char **argv)
|
||||
setup_path();
|
||||
if (!enter_repo(dir, 0))
|
||||
not_found("Not a git repository: '%s'", dir);
|
||||
if (!getenv("GIT_HTTP_EXPORT_ALL") &&
|
||||
access("git-daemon-export-ok", F_OK) )
|
||||
not_found("Repository not exported: '%s'", dir);
|
||||
|
||||
git_config(http_config, NULL);
|
||||
cmd->imp(cmd_arg);
|
||||
|
||||
@@ -965,17 +965,13 @@ static struct store *imap_open_store(struct imap_server_conf *srvc)
|
||||
/* open connection to IMAP server */
|
||||
|
||||
if (srvc->tunnel) {
|
||||
const char *argv[4];
|
||||
const char *argv[] = { srvc->tunnel, NULL };
|
||||
struct child_process tunnel = {0};
|
||||
|
||||
imap_info("Starting tunnel '%s'... ", srvc->tunnel);
|
||||
|
||||
argv[0] = "sh";
|
||||
argv[1] = "-c";
|
||||
argv[2] = srvc->tunnel;
|
||||
argv[3] = NULL;
|
||||
|
||||
tunnel.argv = argv;
|
||||
tunnel.use_shell = 1;
|
||||
tunnel.in = -1;
|
||||
tunnel.out = -1;
|
||||
if (start_command(&tunnel))
|
||||
|
||||
@@ -175,7 +175,7 @@ static int ll_ext_merge(const struct ll_merge_driver *fn,
|
||||
{ "B", temp[2] },
|
||||
{ NULL }
|
||||
};
|
||||
const char *args[] = { "sh", "-c", NULL, NULL };
|
||||
const char *args[] = { NULL, NULL };
|
||||
int status, fd, i;
|
||||
struct stat st;
|
||||
|
||||
@@ -190,8 +190,8 @@ static int ll_ext_merge(const struct ll_merge_driver *fn,
|
||||
|
||||
strbuf_expand(&cmd, fn->cmdline, strbuf_expand_dict_cb, &dict);
|
||||
|
||||
args[2] = cmd.buf;
|
||||
status = run_command_v_opt(args, 0);
|
||||
args[0] = cmd.buf;
|
||||
status = run_command_v_opt(args, RUN_USING_SHELL);
|
||||
fd = open(temp[1], O_RDONLY);
|
||||
if (fd < 0)
|
||||
goto bad;
|
||||
|
||||
5
pager.c
5
pager.c
@@ -28,7 +28,7 @@ static void pager_preexec(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char *pager_argv[] = { "sh", "-c", NULL, NULL };
|
||||
static const char *pager_argv[] = { NULL, NULL };
|
||||
static struct child_process pager_process;
|
||||
|
||||
static void wait_for_pager(void)
|
||||
@@ -81,7 +81,8 @@ void setup_pager(void)
|
||||
spawned_pager = 1; /* means we are emitting to terminal */
|
||||
|
||||
/* spawn the pager */
|
||||
pager_argv[2] = pager;
|
||||
pager_argv[0] = pager;
|
||||
pager_process.use_shell = 1;
|
||||
pager_process.argv = pager_argv;
|
||||
pager_process.in = -1;
|
||||
if (!getenv("LESS")) {
|
||||
|
||||
@@ -15,6 +15,50 @@ static inline void dup_devnull(int to)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static const char **prepare_shell_cmd(const char **argv)
|
||||
{
|
||||
int argc, nargc = 0;
|
||||
const char **nargv;
|
||||
|
||||
for (argc = 0; argv[argc]; argc++)
|
||||
; /* just counting */
|
||||
/* +1 for NULL, +3 for "sh -c" plus extra $0 */
|
||||
nargv = xmalloc(sizeof(*nargv) * (argc + 1 + 3));
|
||||
|
||||
if (argc < 1)
|
||||
die("BUG: shell command is empty");
|
||||
|
||||
if (strcspn(argv[0], "|&;<>()$`\\\"' \t\n*?[#~=%") != strlen(argv[0])) {
|
||||
nargv[nargc++] = "sh";
|
||||
nargv[nargc++] = "-c";
|
||||
|
||||
if (argc < 2)
|
||||
nargv[nargc++] = argv[0];
|
||||
else {
|
||||
struct strbuf arg0 = STRBUF_INIT;
|
||||
strbuf_addf(&arg0, "%s \"$@\"", argv[0]);
|
||||
nargv[nargc++] = strbuf_detach(&arg0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
for (argc = 0; argv[argc]; argc++)
|
||||
nargv[nargc++] = argv[argc];
|
||||
nargv[nargc] = NULL;
|
||||
|
||||
return nargv;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
static int execv_shell_cmd(const char **argv)
|
||||
{
|
||||
const char **nargv = prepare_shell_cmd(argv);
|
||||
trace_argv_printf(nargv, "trace: exec:");
|
||||
execvp(nargv[0], (char **)nargv);
|
||||
free(nargv);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int start_command(struct child_process *cmd)
|
||||
{
|
||||
int need_in, need_out, need_err;
|
||||
@@ -123,6 +167,8 @@ fail_pipe:
|
||||
cmd->preexec_cb();
|
||||
if (cmd->git_cmd) {
|
||||
execv_git_cmd(cmd->argv);
|
||||
} else if (cmd->use_shell) {
|
||||
execv_shell_cmd(cmd->argv);
|
||||
} else {
|
||||
execvp(cmd->argv[0], (char *const*) cmd->argv);
|
||||
}
|
||||
@@ -179,6 +225,8 @@ fail_pipe:
|
||||
|
||||
if (cmd->git_cmd) {
|
||||
cmd->argv = prepare_git_cmd(cmd->argv);
|
||||
} else if (cmd->use_shell) {
|
||||
cmd->argv = prepare_shell_cmd(cmd->argv);
|
||||
}
|
||||
|
||||
cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, env);
|
||||
@@ -297,6 +345,7 @@ static void prepare_run_command_v_opt(struct child_process *cmd,
|
||||
cmd->git_cmd = opt & RUN_GIT_CMD ? 1 : 0;
|
||||
cmd->stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0;
|
||||
cmd->silent_exec_failure = opt & RUN_SILENT_EXEC_FAILURE ? 1 : 0;
|
||||
cmd->use_shell = opt & RUN_USING_SHELL ? 1 : 0;
|
||||
}
|
||||
|
||||
int run_command_v_opt(const char **argv, int opt)
|
||||
|
||||
@@ -33,6 +33,7 @@ struct child_process {
|
||||
unsigned git_cmd:1; /* if this is to be git sub-command */
|
||||
unsigned silent_exec_failure:1;
|
||||
unsigned stdout_to_stderr:1;
|
||||
unsigned use_shell:1;
|
||||
void (*preexec_cb)(void);
|
||||
};
|
||||
|
||||
@@ -46,6 +47,7 @@ extern int run_hook(const char *index_file, const char *name, ...);
|
||||
#define RUN_GIT_CMD 2 /*If this is to be git sub-command */
|
||||
#define RUN_COMMAND_STDOUT_TO_STDERR 4
|
||||
#define RUN_SILENT_EXEC_FAILURE 8
|
||||
#define RUN_USING_SHELL 16
|
||||
int run_command_v_opt(const char **argv, int opt);
|
||||
|
||||
/*
|
||||
|
||||
@@ -12,16 +12,29 @@ fi
|
||||
|
||||
HTTPD_PARA=""
|
||||
|
||||
for DEFAULT_HTTPD_PATH in '/usr/sbin/httpd' '/usr/sbin/apache2'
|
||||
do
|
||||
if test -x "$DEFAULT_HTTPD_PATH"
|
||||
then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
for DEFAULT_HTTPD_MODULE_PATH in '/usr/libexec/apache2' \
|
||||
'/usr/lib/apache2/modules' \
|
||||
'/usr/lib64/httpd/modules' \
|
||||
'/usr/lib/httpd/modules'
|
||||
do
|
||||
if test -d "$DEFAULT_HTTPD_MODULE_PATH"
|
||||
then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
case $(uname) in
|
||||
Darwin)
|
||||
DEFAULT_HTTPD_PATH='/usr/sbin/httpd'
|
||||
DEFAULT_HTTPD_MODULE_PATH='/usr/libexec/apache2'
|
||||
HTTPD_PARA="$HTTPD_PARA -DDarwin"
|
||||
;;
|
||||
*)
|
||||
DEFAULT_HTTPD_PATH='/usr/sbin/apache2'
|
||||
DEFAULT_HTTPD_MODULE_PATH='/usr/lib/apache2/modules'
|
||||
;;
|
||||
esac
|
||||
|
||||
LIB_HTTPD_PATH=${LIB_HTTPD_PATH-"$DEFAULT_HTTPD_PATH"}
|
||||
@@ -49,6 +62,11 @@ then
|
||||
say "skipping test, at least Apache version 2 is required"
|
||||
test_done
|
||||
fi
|
||||
if ! test -d "$DEFAULT_HTTPD_MODULE_PATH"
|
||||
then
|
||||
say "Apache module directory not found. Skipping tests."
|
||||
test_done
|
||||
fi
|
||||
|
||||
LIB_HTTPD_MODULE_PATH="$DEFAULT_HTTPD_MODULE_PATH"
|
||||
fi
|
||||
|
||||
@@ -22,8 +22,13 @@ Alias /dumb/ www/
|
||||
|
||||
<Location /smart/>
|
||||
SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
|
||||
SetEnv GIT_HTTP_EXPORT_ALL
|
||||
</Location>
|
||||
<Location /smart_noexport/>
|
||||
SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
|
||||
</Location>
|
||||
ScriptAlias /smart/ ${GIT_EXEC_PATH}/git-http-backend/
|
||||
ScriptAlias /smart_noexport/ ${GIT_EXEC_PATH}/git-http-backend/
|
||||
<Directory ${GIT_EXEC_PATH}>
|
||||
Options None
|
||||
</Directory>
|
||||
|
||||
@@ -4,7 +4,8 @@ test_description='blob conversion via gitattributes'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
cat <<\EOF >rot13.sh
|
||||
cat <<EOF >rot13.sh
|
||||
#!$SHELL_PATH
|
||||
tr \
|
||||
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' \
|
||||
'nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM'
|
||||
|
||||
@@ -48,7 +48,7 @@ test_expect_success 'file is considered binary by plumbing' '
|
||||
|
||||
test_expect_success 'setup textconv filters' '
|
||||
echo file diff=foo >.gitattributes &&
|
||||
git config diff.foo.textconv "$PWD"/hexdump &&
|
||||
git config diff.foo.textconv "\"$(pwd)\""/hexdump &&
|
||||
git config diff.fail.textconv false
|
||||
'
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ chmod +x dump
|
||||
|
||||
test_expect_success 'setup textconv' '
|
||||
echo file diff=foo >.gitattributes &&
|
||||
git config diff.foo.textconv "$PWD"/dump
|
||||
git config diff.foo.textconv "\"$(pwd)\""/dump
|
||||
'
|
||||
|
||||
test_expect_success 'rewrite diff respects textconv' '
|
||||
|
||||
73
t/t5560-http-backend-noserver.sh
Executable file
73
t/t5560-http-backend-noserver.sh
Executable file
@@ -0,0 +1,73 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='test git-http-backend-noserver'
|
||||
. ./test-lib.sh
|
||||
|
||||
HTTPD_DOCUMENT_ROOT_PATH="$TRASH_DIRECTORY"
|
||||
|
||||
run_backend() {
|
||||
echo "$2" |
|
||||
QUERY_STRING="${1#*\?}" \
|
||||
GIT_PROJECT_ROOT="$HTTPD_DOCUMENT_ROOT_PATH" \
|
||||
PATH_INFO="${1%%\?*}" \
|
||||
git http-backend >act.out 2>act.err
|
||||
}
|
||||
|
||||
GET() {
|
||||
export REQUEST_METHOD="GET" &&
|
||||
run_backend "/repo.git/$1" &&
|
||||
unset REQUEST_METHOD &&
|
||||
if ! grep "Status" act.out >act
|
||||
then
|
||||
printf "Status: 200 OK\r\n" >act
|
||||
fi
|
||||
printf "Status: $2\r\n" >exp &&
|
||||
test_cmp exp act
|
||||
}
|
||||
|
||||
POST() {
|
||||
export REQUEST_METHOD="POST" &&
|
||||
export CONTENT_TYPE="application/x-$1-request" &&
|
||||
run_backend "/repo.git/$1" "$2" &&
|
||||
unset REQUEST_METHOD &&
|
||||
unset CONTENT_TYPE &&
|
||||
if ! grep "Status" act.out >act
|
||||
then
|
||||
printf "Status: 200 OK\r\n" >act
|
||||
fi
|
||||
printf "Status: $3\r\n" >exp &&
|
||||
test_cmp exp act
|
||||
}
|
||||
|
||||
log_div() {
|
||||
return 0
|
||||
}
|
||||
|
||||
. "$TEST_DIRECTORY"/t556x_common
|
||||
|
||||
expect_aliased() {
|
||||
export REQUEST_METHOD="GET" &&
|
||||
if test $1 = 0; then
|
||||
run_backend "$2"
|
||||
else
|
||||
run_backend "$2" &&
|
||||
echo "fatal: '$2': aliased" >exp.err &&
|
||||
test_cmp exp.err act.err
|
||||
fi
|
||||
unset REQUEST_METHOD
|
||||
}
|
||||
|
||||
test_expect_success 'http-backend blocks bad PATH_INFO' '
|
||||
config http.getanyfile true &&
|
||||
|
||||
expect_aliased 0 /repo.git/HEAD &&
|
||||
|
||||
expect_aliased 1 /repo.git/../HEAD &&
|
||||
expect_aliased 1 /../etc/passwd &&
|
||||
expect_aliased 1 ../etc/passwd &&
|
||||
expect_aliased 1 /etc//passwd &&
|
||||
expect_aliased 1 /etc/./passwd &&
|
||||
expect_aliased 1 //domain/data.txt
|
||||
'
|
||||
|
||||
test_done
|
||||
@@ -1,260 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='test git-http-backend'
|
||||
. ./test-lib.sh
|
||||
|
||||
if test -n "$NO_CURL"; then
|
||||
say 'skipping test, git built without http support'
|
||||
test_done
|
||||
fi
|
||||
|
||||
LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5560'}
|
||||
. "$TEST_DIRECTORY"/lib-httpd.sh
|
||||
start_httpd
|
||||
|
||||
find_file() {
|
||||
cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
|
||||
find $1 -type f |
|
||||
sed -e 1q
|
||||
}
|
||||
|
||||
config() {
|
||||
git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" config $1 $2
|
||||
}
|
||||
|
||||
GET() {
|
||||
curl --include "$HTTPD_URL/smart/repo.git/$1" >out 2>/dev/null &&
|
||||
tr '\015' Q <out |
|
||||
sed '
|
||||
s/Q$//
|
||||
1q
|
||||
' >act &&
|
||||
echo "HTTP/1.1 $2" >exp &&
|
||||
test_cmp exp act
|
||||
}
|
||||
|
||||
POST() {
|
||||
curl --include --data "$2" \
|
||||
--header "Content-Type: application/x-$1-request" \
|
||||
"$HTTPD_URL/smart/repo.git/$1" >out 2>/dev/null &&
|
||||
tr '\015' Q <out |
|
||||
sed '
|
||||
s/Q$//
|
||||
1q
|
||||
' >act &&
|
||||
echo "HTTP/1.1 $3" >exp &&
|
||||
test_cmp exp act
|
||||
}
|
||||
|
||||
log_div() {
|
||||
echo >>"$HTTPD_ROOT_PATH"/access.log
|
||||
echo "### $1" >>"$HTTPD_ROOT_PATH"/access.log
|
||||
echo "###" >>"$HTTPD_ROOT_PATH"/access.log
|
||||
}
|
||||
|
||||
test_expect_success 'setup repository' '
|
||||
echo content >file &&
|
||||
git add file &&
|
||||
git commit -m one &&
|
||||
|
||||
mkdir "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
|
||||
(cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
|
||||
git --bare init &&
|
||||
: >objects/info/alternates &&
|
||||
: >objects/info/http-alternates
|
||||
) &&
|
||||
git remote add public "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
|
||||
git push public master:master &&
|
||||
|
||||
(cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
|
||||
git repack -a -d
|
||||
) &&
|
||||
|
||||
echo other >file &&
|
||||
git add file &&
|
||||
git commit -m two &&
|
||||
git push public master:master &&
|
||||
|
||||
LOOSE_URL=$(find_file objects/??) &&
|
||||
PACK_URL=$(find_file objects/pack/*.pack) &&
|
||||
IDX_URL=$(find_file objects/pack/*.idx)
|
||||
'
|
||||
|
||||
get_static_files() {
|
||||
GET HEAD "$1" &&
|
||||
GET info/refs "$1" &&
|
||||
GET objects/info/packs "$1" &&
|
||||
GET objects/info/alternates "$1" &&
|
||||
GET objects/info/http-alternates "$1" &&
|
||||
GET $LOOSE_URL "$1" &&
|
||||
GET $PACK_URL "$1" &&
|
||||
GET $IDX_URL "$1"
|
||||
}
|
||||
|
||||
test_expect_success 'direct refs/heads/master not found' '
|
||||
log_div "refs/heads/master"
|
||||
GET refs/heads/master "404 Not Found"
|
||||
'
|
||||
test_expect_success 'static file is ok' '
|
||||
log_div "getanyfile default"
|
||||
get_static_files "200 OK"
|
||||
'
|
||||
test_expect_success 'static file if http.getanyfile true is ok' '
|
||||
log_div "getanyfile true"
|
||||
config http.getanyfile true &&
|
||||
get_static_files "200 OK"
|
||||
'
|
||||
test_expect_success 'static file if http.getanyfile false fails' '
|
||||
log_div "getanyfile false"
|
||||
config http.getanyfile false &&
|
||||
get_static_files "403 Forbidden"
|
||||
'
|
||||
|
||||
test_expect_success 'http.uploadpack default enabled' '
|
||||
log_div "uploadpack default"
|
||||
GET info/refs?service=git-upload-pack "200 OK" &&
|
||||
POST git-upload-pack 0000 "200 OK"
|
||||
'
|
||||
test_expect_success 'http.uploadpack true' '
|
||||
log_div "uploadpack true"
|
||||
config http.uploadpack true &&
|
||||
GET info/refs?service=git-upload-pack "200 OK" &&
|
||||
POST git-upload-pack 0000 "200 OK"
|
||||
'
|
||||
test_expect_success 'http.uploadpack false' '
|
||||
log_div "uploadpack false"
|
||||
config http.uploadpack false &&
|
||||
GET info/refs?service=git-upload-pack "403 Forbidden" &&
|
||||
POST git-upload-pack 0000 "403 Forbidden"
|
||||
'
|
||||
|
||||
test_expect_success 'http.receivepack default disabled' '
|
||||
log_div "receivepack default"
|
||||
GET info/refs?service=git-receive-pack "403 Forbidden" &&
|
||||
POST git-receive-pack 0000 "403 Forbidden"
|
||||
'
|
||||
test_expect_success 'http.receivepack true' '
|
||||
log_div "receivepack true"
|
||||
config http.receivepack true &&
|
||||
GET info/refs?service=git-receive-pack "200 OK" &&
|
||||
POST git-receive-pack 0000 "200 OK"
|
||||
'
|
||||
test_expect_success 'http.receivepack false' '
|
||||
log_div "receivepack false"
|
||||
config http.receivepack false &&
|
||||
GET info/refs?service=git-receive-pack "403 Forbidden" &&
|
||||
POST git-receive-pack 0000 "403 Forbidden"
|
||||
'
|
||||
|
||||
run_backend() {
|
||||
REQUEST_METHOD=GET \
|
||||
GIT_PROJECT_ROOT="$HTTPD_DOCUMENT_ROOT_PATH" \
|
||||
PATH_INFO="$2" \
|
||||
git http-backend >act.out 2>act.err
|
||||
}
|
||||
|
||||
path_info() {
|
||||
if test $1 = 0; then
|
||||
run_backend "$2"
|
||||
else
|
||||
test_must_fail run_backend "$2" &&
|
||||
echo "fatal: '$2': aliased" >exp.err &&
|
||||
test_cmp exp.err act.err
|
||||
fi
|
||||
}
|
||||
|
||||
test_expect_success 'http-backend blocks bad PATH_INFO' '
|
||||
config http.getanyfile true &&
|
||||
|
||||
run_backend 0 /repo.git/HEAD &&
|
||||
|
||||
run_backend 1 /repo.git/../HEAD &&
|
||||
run_backend 1 /../etc/passwd &&
|
||||
run_backend 1 ../etc/passwd &&
|
||||
run_backend 1 /etc//passwd &&
|
||||
run_backend 1 /etc/./passwd &&
|
||||
run_backend 1 /etc/.../passwd &&
|
||||
run_backend 1 //domain/data.txt
|
||||
'
|
||||
|
||||
cat >exp <<EOF
|
||||
|
||||
### refs/heads/master
|
||||
###
|
||||
GET /smart/repo.git/refs/heads/master HTTP/1.1 404 -
|
||||
|
||||
### getanyfile default
|
||||
###
|
||||
GET /smart/repo.git/HEAD HTTP/1.1 200
|
||||
GET /smart/repo.git/info/refs HTTP/1.1 200
|
||||
GET /smart/repo.git/objects/info/packs HTTP/1.1 200
|
||||
GET /smart/repo.git/objects/info/alternates HTTP/1.1 200 -
|
||||
GET /smart/repo.git/objects/info/http-alternates HTTP/1.1 200 -
|
||||
GET /smart/repo.git/$LOOSE_URL HTTP/1.1 200
|
||||
GET /smart/repo.git/$PACK_URL HTTP/1.1 200
|
||||
GET /smart/repo.git/$IDX_URL HTTP/1.1 200
|
||||
|
||||
### getanyfile true
|
||||
###
|
||||
GET /smart/repo.git/HEAD HTTP/1.1 200
|
||||
GET /smart/repo.git/info/refs HTTP/1.1 200
|
||||
GET /smart/repo.git/objects/info/packs HTTP/1.1 200
|
||||
GET /smart/repo.git/objects/info/alternates HTTP/1.1 200 -
|
||||
GET /smart/repo.git/objects/info/http-alternates HTTP/1.1 200 -
|
||||
GET /smart/repo.git/$LOOSE_URL HTTP/1.1 200
|
||||
GET /smart/repo.git/$PACK_URL HTTP/1.1 200
|
||||
GET /smart/repo.git/$IDX_URL HTTP/1.1 200
|
||||
|
||||
### getanyfile false
|
||||
###
|
||||
GET /smart/repo.git/HEAD HTTP/1.1 403 -
|
||||
GET /smart/repo.git/info/refs HTTP/1.1 403 -
|
||||
GET /smart/repo.git/objects/info/packs HTTP/1.1 403 -
|
||||
GET /smart/repo.git/objects/info/alternates HTTP/1.1 403 -
|
||||
GET /smart/repo.git/objects/info/http-alternates HTTP/1.1 403 -
|
||||
GET /smart/repo.git/$LOOSE_URL HTTP/1.1 403 -
|
||||
GET /smart/repo.git/$PACK_URL HTTP/1.1 403 -
|
||||
GET /smart/repo.git/$IDX_URL HTTP/1.1 403 -
|
||||
|
||||
### uploadpack default
|
||||
###
|
||||
GET /smart/repo.git/info/refs?service=git-upload-pack HTTP/1.1 200
|
||||
POST /smart/repo.git/git-upload-pack HTTP/1.1 200 -
|
||||
|
||||
### uploadpack true
|
||||
###
|
||||
GET /smart/repo.git/info/refs?service=git-upload-pack HTTP/1.1 200
|
||||
POST /smart/repo.git/git-upload-pack HTTP/1.1 200 -
|
||||
|
||||
### uploadpack false
|
||||
###
|
||||
GET /smart/repo.git/info/refs?service=git-upload-pack HTTP/1.1 403 -
|
||||
POST /smart/repo.git/git-upload-pack HTTP/1.1 403 -
|
||||
|
||||
### receivepack default
|
||||
###
|
||||
GET /smart/repo.git/info/refs?service=git-receive-pack HTTP/1.1 403 -
|
||||
POST /smart/repo.git/git-receive-pack HTTP/1.1 403 -
|
||||
|
||||
### receivepack true
|
||||
###
|
||||
GET /smart/repo.git/info/refs?service=git-receive-pack HTTP/1.1 200
|
||||
POST /smart/repo.git/git-receive-pack HTTP/1.1 200 -
|
||||
|
||||
### receivepack false
|
||||
###
|
||||
GET /smart/repo.git/info/refs?service=git-receive-pack HTTP/1.1 403 -
|
||||
POST /smart/repo.git/git-receive-pack HTTP/1.1 403 -
|
||||
EOF
|
||||
test_expect_success 'server request log matches test results' '
|
||||
sed -e "
|
||||
s/^.* \"//
|
||||
s/\"//
|
||||
s/ [1-9][0-9]*\$//
|
||||
s/^GET /GET /
|
||||
" >act <"$HTTPD_ROOT_PATH"/access.log &&
|
||||
test_cmp exp act
|
||||
'
|
||||
|
||||
stop_httpd
|
||||
test_done
|
||||
149
t/t5561-http-backend.sh
Executable file
149
t/t5561-http-backend.sh
Executable file
@@ -0,0 +1,149 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='test git-http-backend'
|
||||
. ./test-lib.sh
|
||||
|
||||
if test -n "$NO_CURL"; then
|
||||
say 'skipping test, git built without http support'
|
||||
test_done
|
||||
fi
|
||||
|
||||
LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5561'}
|
||||
. "$TEST_DIRECTORY"/lib-httpd.sh
|
||||
start_httpd
|
||||
|
||||
GET() {
|
||||
curl --include "$HTTPD_URL/$SMART/repo.git/$1" >out 2>/dev/null &&
|
||||
tr '\015' Q <out |
|
||||
sed '
|
||||
s/Q$//
|
||||
1q
|
||||
' >act &&
|
||||
echo "HTTP/1.1 $2" >exp &&
|
||||
test_cmp exp act
|
||||
}
|
||||
|
||||
POST() {
|
||||
curl --include --data "$2" \
|
||||
--header "Content-Type: application/x-$1-request" \
|
||||
"$HTTPD_URL/smart/repo.git/$1" >out 2>/dev/null &&
|
||||
tr '\015' Q <out |
|
||||
sed '
|
||||
s/Q$//
|
||||
1q
|
||||
' >act &&
|
||||
echo "HTTP/1.1 $3" >exp &&
|
||||
test_cmp exp act
|
||||
}
|
||||
|
||||
log_div() {
|
||||
echo >>"$HTTPD_ROOT_PATH"/access.log
|
||||
echo "### $1" >>"$HTTPD_ROOT_PATH"/access.log
|
||||
echo "###" >>"$HTTPD_ROOT_PATH"/access.log
|
||||
}
|
||||
|
||||
. "$TEST_DIRECTORY"/t556x_common
|
||||
|
||||
cat >exp <<EOF
|
||||
|
||||
### refs/heads/master
|
||||
###
|
||||
GET /smart/repo.git/refs/heads/master HTTP/1.1 404 -
|
||||
|
||||
### getanyfile default
|
||||
###
|
||||
GET /smart/repo.git/HEAD HTTP/1.1 200
|
||||
GET /smart/repo.git/info/refs HTTP/1.1 200
|
||||
GET /smart/repo.git/objects/info/packs HTTP/1.1 200
|
||||
GET /smart/repo.git/objects/info/alternates HTTP/1.1 200 -
|
||||
GET /smart/repo.git/objects/info/http-alternates HTTP/1.1 200 -
|
||||
GET /smart/repo.git/$LOOSE_URL HTTP/1.1 200
|
||||
GET /smart/repo.git/$PACK_URL HTTP/1.1 200
|
||||
GET /smart/repo.git/$IDX_URL HTTP/1.1 200
|
||||
|
||||
### no git-daemon-export-ok
|
||||
###
|
||||
GET /smart_noexport/repo.git/HEAD HTTP/1.1 404 -
|
||||
GET /smart_noexport/repo.git/info/refs HTTP/1.1 404 -
|
||||
GET /smart_noexport/repo.git/objects/info/packs HTTP/1.1 404 -
|
||||
GET /smart_noexport/repo.git/objects/info/alternates HTTP/1.1 404 -
|
||||
GET /smart_noexport/repo.git/objects/info/http-alternates HTTP/1.1 404 -
|
||||
GET /smart_noexport/repo.git/$LOOSE_URL HTTP/1.1 404 -
|
||||
GET /smart_noexport/repo.git/$PACK_URL HTTP/1.1 404 -
|
||||
GET /smart_noexport/repo.git/$IDX_URL HTTP/1.1 404 -
|
||||
|
||||
### git-daemon-export-ok
|
||||
###
|
||||
GET /smart_noexport/repo.git/HEAD HTTP/1.1 200
|
||||
GET /smart_noexport/repo.git/info/refs HTTP/1.1 200
|
||||
GET /smart_noexport/repo.git/objects/info/packs HTTP/1.1 200
|
||||
GET /smart_noexport/repo.git/objects/info/alternates HTTP/1.1 200 -
|
||||
GET /smart_noexport/repo.git/objects/info/http-alternates HTTP/1.1 200 -
|
||||
GET /smart_noexport/repo.git/$LOOSE_URL HTTP/1.1 200
|
||||
GET /smart_noexport/repo.git/$PACK_URL HTTP/1.1 200
|
||||
GET /smart_noexport/repo.git/$IDX_URL HTTP/1.1 200
|
||||
|
||||
### getanyfile true
|
||||
###
|
||||
GET /smart/repo.git/HEAD HTTP/1.1 200
|
||||
GET /smart/repo.git/info/refs HTTP/1.1 200
|
||||
GET /smart/repo.git/objects/info/packs HTTP/1.1 200
|
||||
GET /smart/repo.git/objects/info/alternates HTTP/1.1 200 -
|
||||
GET /smart/repo.git/objects/info/http-alternates HTTP/1.1 200 -
|
||||
GET /smart/repo.git/$LOOSE_URL HTTP/1.1 200
|
||||
GET /smart/repo.git/$PACK_URL HTTP/1.1 200
|
||||
GET /smart/repo.git/$IDX_URL HTTP/1.1 200
|
||||
|
||||
### getanyfile false
|
||||
###
|
||||
GET /smart/repo.git/HEAD HTTP/1.1 403 -
|
||||
GET /smart/repo.git/info/refs HTTP/1.1 403 -
|
||||
GET /smart/repo.git/objects/info/packs HTTP/1.1 403 -
|
||||
GET /smart/repo.git/objects/info/alternates HTTP/1.1 403 -
|
||||
GET /smart/repo.git/objects/info/http-alternates HTTP/1.1 403 -
|
||||
GET /smart/repo.git/$LOOSE_URL HTTP/1.1 403 -
|
||||
GET /smart/repo.git/$PACK_URL HTTP/1.1 403 -
|
||||
GET /smart/repo.git/$IDX_URL HTTP/1.1 403 -
|
||||
|
||||
### uploadpack default
|
||||
###
|
||||
GET /smart/repo.git/info/refs?service=git-upload-pack HTTP/1.1 200
|
||||
POST /smart/repo.git/git-upload-pack HTTP/1.1 200 -
|
||||
|
||||
### uploadpack true
|
||||
###
|
||||
GET /smart/repo.git/info/refs?service=git-upload-pack HTTP/1.1 200
|
||||
POST /smart/repo.git/git-upload-pack HTTP/1.1 200 -
|
||||
|
||||
### uploadpack false
|
||||
###
|
||||
GET /smart/repo.git/info/refs?service=git-upload-pack HTTP/1.1 403 -
|
||||
POST /smart/repo.git/git-upload-pack HTTP/1.1 403 -
|
||||
|
||||
### receivepack default
|
||||
###
|
||||
GET /smart/repo.git/info/refs?service=git-receive-pack HTTP/1.1 403 -
|
||||
POST /smart/repo.git/git-receive-pack HTTP/1.1 403 -
|
||||
|
||||
### receivepack true
|
||||
###
|
||||
GET /smart/repo.git/info/refs?service=git-receive-pack HTTP/1.1 200
|
||||
POST /smart/repo.git/git-receive-pack HTTP/1.1 200 -
|
||||
|
||||
### receivepack false
|
||||
###
|
||||
GET /smart/repo.git/info/refs?service=git-receive-pack HTTP/1.1 403 -
|
||||
POST /smart/repo.git/git-receive-pack HTTP/1.1 403 -
|
||||
EOF
|
||||
test_expect_success 'server request log matches test results' '
|
||||
sed -e "
|
||||
s/^.* \"//
|
||||
s/\"//
|
||||
s/ [1-9][0-9]*\$//
|
||||
s/^GET /GET /
|
||||
" >act <"$HTTPD_ROOT_PATH"/access.log &&
|
||||
test_cmp exp act
|
||||
'
|
||||
|
||||
stop_httpd
|
||||
test_done
|
||||
122
t/t556x_common
Executable file
122
t/t556x_common
Executable file
@@ -0,0 +1,122 @@
|
||||
#!/bin/sh
|
||||
|
||||
find_file() {
|
||||
cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
|
||||
find $1 -type f |
|
||||
sed -e 1q
|
||||
}
|
||||
|
||||
config() {
|
||||
git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" config $1 $2
|
||||
}
|
||||
|
||||
test_expect_success 'setup repository' '
|
||||
echo content >file &&
|
||||
git add file &&
|
||||
git commit -m one &&
|
||||
|
||||
mkdir "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
|
||||
(cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
|
||||
git --bare init &&
|
||||
: >objects/info/alternates &&
|
||||
: >objects/info/http-alternates
|
||||
) &&
|
||||
git remote add public "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
|
||||
git push public master:master &&
|
||||
|
||||
(cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
|
||||
git repack -a -d
|
||||
) &&
|
||||
|
||||
echo other >file &&
|
||||
git add file &&
|
||||
git commit -m two &&
|
||||
git push public master:master &&
|
||||
|
||||
LOOSE_URL=$(find_file objects/??) &&
|
||||
PACK_URL=$(find_file objects/pack/*.pack) &&
|
||||
IDX_URL=$(find_file objects/pack/*.idx)
|
||||
'
|
||||
|
||||
get_static_files() {
|
||||
GET HEAD "$1" &&
|
||||
GET info/refs "$1" &&
|
||||
GET objects/info/packs "$1" &&
|
||||
GET objects/info/alternates "$1" &&
|
||||
GET objects/info/http-alternates "$1" &&
|
||||
GET $LOOSE_URL "$1" &&
|
||||
GET $PACK_URL "$1" &&
|
||||
GET $IDX_URL "$1"
|
||||
}
|
||||
|
||||
SMART=smart
|
||||
export GIT_HTTP_EXPORT_ALL=1
|
||||
test_expect_success 'direct refs/heads/master not found' '
|
||||
log_div "refs/heads/master"
|
||||
GET refs/heads/master "404 Not Found"
|
||||
'
|
||||
test_expect_success 'static file is ok' '
|
||||
log_div "getanyfile default"
|
||||
get_static_files "200 OK"
|
||||
'
|
||||
SMART=smart_noexport
|
||||
unset GIT_HTTP_EXPORT_ALL
|
||||
test_expect_success 'no export by default' '
|
||||
log_div "no git-daemon-export-ok"
|
||||
get_static_files "404 Not Found"
|
||||
'
|
||||
test_expect_success 'export if git-daemon-export-ok' '
|
||||
log_div "git-daemon-export-ok"
|
||||
(cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
|
||||
touch git-daemon-export-ok
|
||||
) &&
|
||||
get_static_files "200 OK"
|
||||
'
|
||||
SMART=smart
|
||||
export GIT_HTTP_EXPORT_ALL=1
|
||||
test_expect_success 'static file if http.getanyfile true is ok' '
|
||||
log_div "getanyfile true"
|
||||
config http.getanyfile true &&
|
||||
get_static_files "200 OK"
|
||||
'
|
||||
test_expect_success 'static file if http.getanyfile false fails' '
|
||||
log_div "getanyfile false"
|
||||
config http.getanyfile false &&
|
||||
get_static_files "403 Forbidden"
|
||||
'
|
||||
|
||||
test_expect_success 'http.uploadpack default enabled' '
|
||||
log_div "uploadpack default"
|
||||
GET info/refs?service=git-upload-pack "200 OK" &&
|
||||
POST git-upload-pack 0000 "200 OK"
|
||||
'
|
||||
test_expect_success 'http.uploadpack true' '
|
||||
log_div "uploadpack true"
|
||||
config http.uploadpack true &&
|
||||
GET info/refs?service=git-upload-pack "200 OK" &&
|
||||
POST git-upload-pack 0000 "200 OK"
|
||||
'
|
||||
test_expect_success 'http.uploadpack false' '
|
||||
log_div "uploadpack false"
|
||||
config http.uploadpack false &&
|
||||
GET info/refs?service=git-upload-pack "403 Forbidden" &&
|
||||
POST git-upload-pack 0000 "403 Forbidden"
|
||||
'
|
||||
|
||||
test_expect_success 'http.receivepack default disabled' '
|
||||
log_div "receivepack default"
|
||||
GET info/refs?service=git-receive-pack "403 Forbidden" &&
|
||||
POST git-receive-pack 0000 "403 Forbidden"
|
||||
'
|
||||
test_expect_success 'http.receivepack true' '
|
||||
log_div "receivepack true"
|
||||
config http.receivepack true &&
|
||||
GET info/refs?service=git-receive-pack "200 OK" &&
|
||||
POST git-receive-pack 0000 "200 OK"
|
||||
'
|
||||
test_expect_success 'http.receivepack false' '
|
||||
log_div "receivepack false"
|
||||
config http.receivepack false &&
|
||||
GET info/refs?service=git-receive-pack "403 Forbidden" &&
|
||||
POST git-receive-pack 0000 "403 Forbidden"
|
||||
'
|
||||
@@ -27,7 +27,8 @@ test_expect_success 'redirected clone' '
|
||||
'
|
||||
test_expect_success 'redirected clone -v' '
|
||||
|
||||
git clone -v "file://$(pwd)/parent" clone-redirected-v >out 2>err &&
|
||||
git clone --progress "file://$(pwd)/parent" clone-redirected-progress \
|
||||
>out 2>err &&
|
||||
test -s err
|
||||
|
||||
'
|
||||
|
||||
@@ -73,13 +73,13 @@ test_expect_success 'setting up branches to test with unmerged entries' '
|
||||
git checkout branch1 &&
|
||||
test_commit B1 file1 &&
|
||||
git checkout branch2 &&
|
||||
test_commit B2 file1
|
||||
test_commit B file1
|
||||
'
|
||||
|
||||
while read W1 I1 H1 T opt W2 I2 H2
|
||||
do
|
||||
test_expect_success "check: $W1 $I1 $H1 $T --$opt $W2 $I2 $H2" '
|
||||
git reset --hard B2 &&
|
||||
git reset --hard B &&
|
||||
test_must_fail git merge branch1 &&
|
||||
cat file1 >X_file1 &&
|
||||
if test "$W2" != "XXXXX"
|
||||
@@ -100,14 +100,14 @@ do
|
||||
fi
|
||||
'
|
||||
done <<\EOF
|
||||
X U C D soft XXXXX
|
||||
X U C D mixed X D D
|
||||
X U C D hard D D D
|
||||
X U C D merge D D D
|
||||
X U C C soft XXXXX
|
||||
X U C C mixed X C C
|
||||
X U C C hard C C C
|
||||
X U C C merge C C C
|
||||
X U B C soft XXXXX
|
||||
X U B C mixed X C C
|
||||
X U B C hard C C C
|
||||
X U B C merge C C C
|
||||
X U B B soft XXXXX
|
||||
X U B B mixed X B B
|
||||
X U B B hard B B B
|
||||
X U B B merge B B B
|
||||
EOF
|
||||
|
||||
test_done
|
||||
|
||||
@@ -542,4 +542,61 @@ test_expect_success 'switch out of non-branch' '
|
||||
! grep "^Previous HEAD" error.log
|
||||
'
|
||||
|
||||
(
|
||||
echo "#!$SHELL_PATH"
|
||||
cat <<\EOF
|
||||
O=$1 A=$2 B=$3
|
||||
cat "$A" >.tmp
|
||||
exec >"$A"
|
||||
echo '<<<<<<< filfre-theirs'
|
||||
cat "$B"
|
||||
echo '||||||| filfre-common'
|
||||
cat "$O"
|
||||
echo '======='
|
||||
cat ".tmp"
|
||||
echo '>>>>>>> filfre-ours'
|
||||
rm -f .tmp
|
||||
exit 1
|
||||
EOF
|
||||
) >filfre.sh
|
||||
chmod +x filfre.sh
|
||||
|
||||
test_expect_success 'custom merge driver with checkout -m' '
|
||||
git reset --hard &&
|
||||
|
||||
git config merge.filfre.driver "./filfre.sh %O %A %B" &&
|
||||
git config merge.filfre.name "Feel-free merge driver" &&
|
||||
git config merge.filfre.recursive binary &&
|
||||
echo "arm merge=filfre" >.gitattributes &&
|
||||
|
||||
git checkout -b left &&
|
||||
echo neutral >arm &&
|
||||
git add arm .gitattributes &&
|
||||
test_tick &&
|
||||
git commit -m neutral &&
|
||||
git branch right &&
|
||||
|
||||
echo left >arm &&
|
||||
test_tick &&
|
||||
git commit -a -m left &&
|
||||
git checkout right &&
|
||||
|
||||
echo right >arm &&
|
||||
test_tick &&
|
||||
git commit -a -m right &&
|
||||
|
||||
test_must_fail git merge left &&
|
||||
(
|
||||
for t in filfre-common left right
|
||||
do
|
||||
grep $t arm || exit 1
|
||||
done
|
||||
exit 0
|
||||
) &&
|
||||
|
||||
mv arm expect &&
|
||||
git checkout -m arm &&
|
||||
test_cmp expect arm
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -267,4 +267,113 @@ test_expect_success 'A single-liner subject with a token plus colon is not a foo
|
||||
|
||||
'
|
||||
|
||||
cat >.git/FAKE_EDITOR <<EOF
|
||||
#!$SHELL_PATH
|
||||
mv "\$1" "\$1.orig"
|
||||
(
|
||||
echo message
|
||||
cat "\$1.orig"
|
||||
) >"\$1"
|
||||
EOF
|
||||
|
||||
echo '## Custom template' >template
|
||||
|
||||
clear_config () {
|
||||
(
|
||||
git config --unset-all "$1"
|
||||
case $? in
|
||||
0|5) exit 0 ;;
|
||||
*) exit 1 ;;
|
||||
esac
|
||||
)
|
||||
}
|
||||
|
||||
try_commit () {
|
||||
git reset --hard &&
|
||||
echo >>negative &&
|
||||
GIT_EDITOR=.git/FAKE_EDITOR git commit -a $* $use_template &&
|
||||
case "$use_template" in
|
||||
'')
|
||||
! grep "^## Custom template" .git/COMMIT_EDITMSG ;;
|
||||
*)
|
||||
grep "^## Custom template" .git/COMMIT_EDITMSG ;;
|
||||
esac
|
||||
}
|
||||
|
||||
try_commit_status_combo () {
|
||||
|
||||
test_expect_success 'commit' '
|
||||
clear_config commit.status &&
|
||||
try_commit "" &&
|
||||
grep "^# Changes to be committed:" .git/COMMIT_EDITMSG
|
||||
'
|
||||
|
||||
test_expect_success 'commit' '
|
||||
clear_config commit.status &&
|
||||
try_commit "" &&
|
||||
grep "^# Changes to be committed:" .git/COMMIT_EDITMSG
|
||||
'
|
||||
|
||||
test_expect_success 'commit --status' '
|
||||
clear_config commit.status &&
|
||||
try_commit --status &&
|
||||
grep "^# Changes to be committed:" .git/COMMIT_EDITMSG
|
||||
'
|
||||
|
||||
test_expect_success 'commit --no-status' '
|
||||
clear_config commit.status &&
|
||||
try_commit --no-status
|
||||
! grep "^# Changes to be committed:" .git/COMMIT_EDITMSG
|
||||
'
|
||||
|
||||
test_expect_success 'commit with commit.status = yes' '
|
||||
clear_config commit.status &&
|
||||
git config commit.status yes &&
|
||||
try_commit "" &&
|
||||
grep "^# Changes to be committed:" .git/COMMIT_EDITMSG
|
||||
'
|
||||
|
||||
test_expect_success 'commit with commit.status = no' '
|
||||
clear_config commit.status &&
|
||||
git config commit.status no &&
|
||||
try_commit "" &&
|
||||
! grep "^# Changes to be committed:" .git/COMMIT_EDITMSG
|
||||
'
|
||||
|
||||
test_expect_success 'commit --status with commit.status = yes' '
|
||||
clear_config commit.status &&
|
||||
git config commit.status yes &&
|
||||
try_commit --status &&
|
||||
grep "^# Changes to be committed:" .git/COMMIT_EDITMSG
|
||||
'
|
||||
|
||||
test_expect_success 'commit --no-status with commit.status = yes' '
|
||||
clear_config commit.status &&
|
||||
git config commit.status yes &&
|
||||
try_commit --no-status &&
|
||||
! grep "^# Changes to be committed:" .git/COMMIT_EDITMSG
|
||||
'
|
||||
|
||||
test_expect_success 'commit --status with commit.status = no' '
|
||||
clear_config commit.status &&
|
||||
git config commit.status no &&
|
||||
try_commit --status &&
|
||||
grep "^# Changes to be committed:" .git/COMMIT_EDITMSG
|
||||
'
|
||||
|
||||
test_expect_success 'commit --no-status with commit.status = no' '
|
||||
clear_config commit.status &&
|
||||
git config commit.status no &&
|
||||
try_commit --no-status &&
|
||||
! grep "^# Changes to be committed:" .git/COMMIT_EDITMSG
|
||||
'
|
||||
|
||||
}
|
||||
|
||||
try_commit_status_combo
|
||||
|
||||
use_template="-t template"
|
||||
|
||||
try_commit_status_combo
|
||||
|
||||
test_done
|
||||
|
||||
@@ -1254,4 +1254,156 @@ test_expect_success \
|
||||
'Q: verify note for third commit' \
|
||||
'git cat-file blob refs/notes/foobar:$commit3 >actual && test_cmp expect actual'
|
||||
|
||||
###
|
||||
### series R (feature and option)
|
||||
###
|
||||
|
||||
cat >input <<EOF
|
||||
feature no-such-feature-exists
|
||||
EOF
|
||||
|
||||
test_expect_success 'R: abort on unsupported feature' '
|
||||
test_must_fail git fast-import <input
|
||||
'
|
||||
|
||||
cat >input <<EOF
|
||||
feature date-format=now
|
||||
EOF
|
||||
|
||||
test_expect_success 'R: supported feature is accepted' '
|
||||
git fast-import <input
|
||||
'
|
||||
|
||||
cat >input << EOF
|
||||
blob
|
||||
data 3
|
||||
hi
|
||||
feature date-format=now
|
||||
EOF
|
||||
|
||||
test_expect_success 'R: abort on receiving feature after data command' '
|
||||
test_must_fail git fast-import <input
|
||||
'
|
||||
|
||||
cat >input << EOF
|
||||
feature import-marks=git.marks
|
||||
feature import-marks=git2.marks
|
||||
EOF
|
||||
|
||||
test_expect_success 'R: only one import-marks feature allowed per stream' '
|
||||
test_must_fail git fast-import <input
|
||||
'
|
||||
|
||||
cat >input << EOF
|
||||
feature export-marks=git.marks
|
||||
blob
|
||||
mark :1
|
||||
data 3
|
||||
hi
|
||||
|
||||
EOF
|
||||
|
||||
test_expect_success \
|
||||
'R: export-marks feature results in a marks file being created' \
|
||||
'cat input | git fast-import &&
|
||||
grep :1 git.marks'
|
||||
|
||||
test_expect_success \
|
||||
'R: export-marks options can be overriden by commandline options' \
|
||||
'cat input | git fast-import --export-marks=other.marks &&
|
||||
grep :1 other.marks'
|
||||
|
||||
cat >input << EOF
|
||||
feature import-marks=marks.out
|
||||
feature export-marks=marks.new
|
||||
EOF
|
||||
|
||||
test_expect_success \
|
||||
'R: import to output marks works without any content' \
|
||||
'cat input | git fast-import &&
|
||||
test_cmp marks.out marks.new'
|
||||
|
||||
cat >input <<EOF
|
||||
feature import-marks=nonexistant.marks
|
||||
feature export-marks=marks.new
|
||||
EOF
|
||||
|
||||
test_expect_success \
|
||||
'R: import marks prefers commandline marks file over the stream' \
|
||||
'cat input | git fast-import --import-marks=marks.out &&
|
||||
test_cmp marks.out marks.new'
|
||||
|
||||
|
||||
cat >input <<EOF
|
||||
feature import-marks=nonexistant.marks
|
||||
feature export-marks=combined.marks
|
||||
EOF
|
||||
|
||||
test_expect_success 'R: multiple --import-marks= should be honoured' '
|
||||
head -n2 marks.out > one.marks &&
|
||||
tail -n +3 marks.out > two.marks &&
|
||||
git fast-import --import-marks=one.marks --import-marks=two.marks <input &&
|
||||
test_cmp marks.out combined.marks
|
||||
'
|
||||
|
||||
cat >input <<EOF
|
||||
feature relative-marks
|
||||
feature import-marks=relative.in
|
||||
feature export-marks=relative.out
|
||||
EOF
|
||||
|
||||
test_expect_success 'R: feature relative-marks should be honoured' '
|
||||
mkdir -p .git/info/fast-import/ &&
|
||||
cp marks.new .git/info/fast-import/relative.in &&
|
||||
git fast-import <input &&
|
||||
test_cmp marks.new .git/info/fast-import/relative.out
|
||||
'
|
||||
|
||||
cat >input <<EOF
|
||||
feature relative-marks
|
||||
feature import-marks=relative.in
|
||||
feature no-relative-marks
|
||||
feature export-marks=non-relative.out
|
||||
EOF
|
||||
|
||||
test_expect_success 'R: feature no-relative-marks should be honoured' '
|
||||
git fast-import <input &&
|
||||
test_cmp marks.new non-relative.out
|
||||
'
|
||||
|
||||
cat >input << EOF
|
||||
option git quiet
|
||||
blob
|
||||
data 3
|
||||
hi
|
||||
|
||||
EOF
|
||||
|
||||
touch empty
|
||||
|
||||
test_expect_success 'R: quiet option results in no stats being output' '
|
||||
cat input | git fast-import 2> output &&
|
||||
test_cmp empty output
|
||||
'
|
||||
|
||||
cat >input <<EOF
|
||||
option git non-existing-option
|
||||
EOF
|
||||
|
||||
test_expect_success 'R: die on unknown option' '
|
||||
test_must_fail git fast-import <input
|
||||
'
|
||||
|
||||
test_expect_success 'R: unknown commandline options are rejected' '\
|
||||
test_must_fail git fast-import --non-existing-option < /dev/null
|
||||
'
|
||||
|
||||
cat >input <<EOF
|
||||
option non-existing-vcs non-existing-option
|
||||
EOF
|
||||
|
||||
test_expect_success 'R: ignore non-git options' '
|
||||
git fast-import <input
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -273,7 +273,7 @@ static void standard_options(struct transport *t)
|
||||
char buf[16];
|
||||
int n;
|
||||
int v = t->verbose;
|
||||
int no_progress = v < 0 || (!t->progress && !isatty(1));
|
||||
int no_progress = v < 0 || (!t->progress && !isatty(2));
|
||||
|
||||
set_helper_option(t, "progress", !no_progress ? "true" : "false");
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ static const char *rsync_url(const char *url)
|
||||
static struct ref *get_refs_via_rsync(struct transport *transport, int for_push)
|
||||
{
|
||||
struct strbuf buf = STRBUF_INIT, temp_dir = STRBUF_INIT;
|
||||
struct ref dummy, *tail = &dummy;
|
||||
struct ref dummy = {0}, *tail = &dummy;
|
||||
struct child_process rsync;
|
||||
const char *args[5];
|
||||
int temp_dir_len;
|
||||
@@ -478,7 +478,7 @@ static int fetch_refs_via_pack(struct transport *transport,
|
||||
args.include_tag = data->options.followtags;
|
||||
args.verbose = (transport->verbose > 0);
|
||||
args.quiet = (transport->verbose < 0);
|
||||
args.no_progress = args.quiet || (!transport->progress && !isatty(1));
|
||||
args.no_progress = args.quiet || (!transport->progress && !isatty(2));
|
||||
args.depth = data->options.depth;
|
||||
|
||||
for (i = 0; i < nr_heads; i++)
|
||||
|
||||
@@ -74,7 +74,7 @@ struct transport {
|
||||
int (*disconnect)(struct transport *connection);
|
||||
char *pack_lockfile;
|
||||
signed verbose : 3;
|
||||
/* Force progress even if the output is not a tty */
|
||||
/* Force progress even if stderr is not a tty */
|
||||
unsigned progress : 1;
|
||||
/*
|
||||
* If transport is at least potentially smart, this points to
|
||||
|
||||
Reference in New Issue
Block a user