Merge branch 'js/read-tree' into js/c-merge-recursive
* js/read-tree: (107 commits) read-tree: move merge functions to the library read-trees: refactor the unpack_trees() part tar-tree: illustrate an obscure feature better git.c: allow alias expansion without a git directory setup_git_directory_gently: do not barf when GIT_DIR is given. Build on Debian GNU/kFreeBSD Call setup_git_directory() much earlier Call setup_git_directory() early Display an error from update-ref if target ref name is invalid. Fix http-fetch t4103: fix binary patch application test. git-apply -R: binary patches are irreversible for now. Teach git-apply about '-R' Makefile: ssh-pull.o depends on ssh-fetch.c log and diff family: honor config even from subdirectories git-reset: detect update-ref error and report it. lost-found: use fsck-objects --full Teach git-http-fetch the --stdin switch Teach git-local-fetch the --stdin switch Make pull() support fetching multiple targets at once ...
This commit is contained in:
commit
c1a788acee
6
.gitignore
vendored
6
.gitignore
vendored
@ -137,4 +137,10 @@ git-core.spec
|
|||||||
*.[ao]
|
*.[ao]
|
||||||
*.py[co]
|
*.py[co]
|
||||||
config.mak
|
config.mak
|
||||||
|
autom4te.cache
|
||||||
|
config.log
|
||||||
|
config.status
|
||||||
|
config.mak.in
|
||||||
|
config.mak.autogen
|
||||||
|
configure
|
||||||
git-blame
|
git-blame
|
||||||
|
@ -25,10 +25,10 @@ DOC_MAN1=$(patsubst %.txt,%.1,$(MAN1_TXT))
|
|||||||
DOC_MAN7=$(patsubst %.txt,%.7,$(MAN7_TXT))
|
DOC_MAN7=$(patsubst %.txt,%.7,$(MAN7_TXT))
|
||||||
|
|
||||||
prefix?=$(HOME)
|
prefix?=$(HOME)
|
||||||
bin=$(prefix)/bin
|
bindir?=$(prefix)/bin
|
||||||
mandir=$(prefix)/man
|
mandir?=$(prefix)/man
|
||||||
man1=$(mandir)/man1
|
man1dir=$(mandir)/man1
|
||||||
man7=$(mandir)/man7
|
man7dir=$(mandir)/man7
|
||||||
# DESTDIR=
|
# DESTDIR=
|
||||||
|
|
||||||
INSTALL?=install
|
INSTALL?=install
|
||||||
@ -46,15 +46,16 @@ all: html man
|
|||||||
|
|
||||||
html: $(DOC_HTML)
|
html: $(DOC_HTML)
|
||||||
|
|
||||||
|
$(DOC_HTML) $(DOC_MAN1) $(DOC_MAN7): asciidoc.conf
|
||||||
|
|
||||||
man: man1 man7
|
man: man1 man7
|
||||||
man1: $(DOC_MAN1)
|
man1: $(DOC_MAN1)
|
||||||
man7: $(DOC_MAN7)
|
man7: $(DOC_MAN7)
|
||||||
|
|
||||||
install: man
|
install: man
|
||||||
$(INSTALL) -d -m755 $(DESTDIR)$(man1) $(DESTDIR)$(man7)
|
$(INSTALL) -d -m755 $(DESTDIR)$(man1dir) $(DESTDIR)$(man7dir)
|
||||||
$(INSTALL) $(DOC_MAN1) $(DESTDIR)$(man1)
|
$(INSTALL) $(DOC_MAN1) $(DESTDIR)$(man1dir)
|
||||||
$(INSTALL) $(DOC_MAN7) $(DESTDIR)$(man7)
|
$(INSTALL) $(DOC_MAN7) $(DESTDIR)$(man7dir)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
[attributes]
|
[attributes]
|
||||||
caret=^
|
caret=^
|
||||||
|
startsb=[
|
||||||
|
endsb=]
|
||||||
|
|
||||||
ifdef::backend-docbook[]
|
ifdef::backend-docbook[]
|
||||||
[gitlink-inlinemacro]
|
[gitlink-inlinemacro]
|
||||||
|
@ -97,6 +97,12 @@ core.compression::
|
|||||||
compression, and 1..9 are various speed/size tradeoffs, 9 being
|
compression, and 1..9 are various speed/size tradeoffs, 9 being
|
||||||
slowest.
|
slowest.
|
||||||
|
|
||||||
|
core.legacyheaders::
|
||||||
|
A boolean which enables the legacy object header format in case
|
||||||
|
you want to interoperate with old clients accessing the object
|
||||||
|
database directly (where the "http://" and "rsync://" protocols
|
||||||
|
count as direct access).
|
||||||
|
|
||||||
alias.*::
|
alias.*::
|
||||||
Command aliases for the gitlink:git[1] command wrapper - e.g.
|
Command aliases for the gitlink:git[1] command wrapper - e.g.
|
||||||
after defining "alias.last = cat-file commit HEAD", the invocation
|
after defining "alias.last = cat-file commit HEAD", the invocation
|
||||||
@ -193,6 +199,10 @@ merge.summary::
|
|||||||
Whether to include summaries of merged commits in newly created
|
Whether to include summaries of merged commits in newly created
|
||||||
merge commit messages. False by default.
|
merge commit messages. False by default.
|
||||||
|
|
||||||
|
pack.window::
|
||||||
|
The size of the window used by gitlink:git-pack-objects[1] when no
|
||||||
|
window size is given on the command line. Defaults to 10.
|
||||||
|
|
||||||
pull.octopus::
|
pull.octopus::
|
||||||
The default merge strategy to use when pulling multiple branches
|
The default merge strategy to use when pulling multiple branches
|
||||||
at once.
|
at once.
|
||||||
@ -208,6 +218,17 @@ showbranch.default::
|
|||||||
The default set of branches for gitlink:git-show-branch[1].
|
The default set of branches for gitlink:git-show-branch[1].
|
||||||
See gitlink:git-show-branch[1].
|
See gitlink:git-show-branch[1].
|
||||||
|
|
||||||
|
tar.umask::
|
||||||
|
By default, git-link:git-tar-tree[1] sets file and directories modes
|
||||||
|
to 0666 or 0777. While this is both useful and acceptable for projects
|
||||||
|
such as the Linux Kernel, it might be excessive for other projects.
|
||||||
|
With this variable, it becomes possible to tell
|
||||||
|
git-link:git-tar-tree[1] to apply a specific umask to the modes above.
|
||||||
|
The special value "user" indicates that the user's current umask will
|
||||||
|
be used. This should be enough for most projects, as it will lead to
|
||||||
|
the same permissions as git-link:git-checkout[1] would use. The default
|
||||||
|
value remains 0, which means world read-write.
|
||||||
|
|
||||||
user.email::
|
user.email::
|
||||||
Your email address to be recorded in any newly created commits.
|
Your email address to be recorded in any newly created commits.
|
||||||
Can be overridden by the 'GIT_AUTHOR_EMAIL' and 'GIT_COMMITTER_EMAIL'
|
Can be overridden by the 'GIT_AUTHOR_EMAIL' and 'GIT_COMMITTER_EMAIL'
|
||||||
|
@ -8,7 +8,7 @@ git-cvsexportcommit - Export a commit to a CVS checkout
|
|||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
'git-cvsexportcommit' [-h] [-v] [-c] [-p] [-f] [-m msgprefix] [PARENTCOMMIT] COMMITID
|
'git-cvsexportcommit' [-h] [-v] [-c] [-p] [-a] [-f] [-m msgprefix] [PARENTCOMMIT] COMMITID
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
@ -39,6 +39,10 @@ OPTIONS
|
|||||||
Be pedantic (paranoid) when applying patches. Invokes patch with
|
Be pedantic (paranoid) when applying patches. Invokes patch with
|
||||||
--fuzz=0
|
--fuzz=0
|
||||||
|
|
||||||
|
-a::
|
||||||
|
Add authorship information. Adds Author line, and Committer (if
|
||||||
|
different from Author) to the message.
|
||||||
|
|
||||||
-f::
|
-f::
|
||||||
Force the merge even if the files are not up to date.
|
Force the merge even if the files are not up to date.
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ SYNOPSIS
|
|||||||
'git-daemon' [--verbose] [--syslog] [--inetd | --port=n] [--export-all]
|
'git-daemon' [--verbose] [--syslog] [--inetd | --port=n] [--export-all]
|
||||||
[--timeout=n] [--init-timeout=n] [--strict-paths]
|
[--timeout=n] [--init-timeout=n] [--strict-paths]
|
||||||
[--base-path=path] [--user-path | --user-path=path]
|
[--base-path=path] [--user-path | --user-path=path]
|
||||||
[directory...]
|
[--reuseaddr] [--detach] [--pid-file=file] [directory...]
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
@ -82,6 +82,17 @@ OPTIONS
|
|||||||
--verbose::
|
--verbose::
|
||||||
Log details about the incoming connections and requested files.
|
Log details about the incoming connections and requested files.
|
||||||
|
|
||||||
|
--reuseaddr::
|
||||||
|
Use SO_REUSEADDR when binding the listening socket.
|
||||||
|
This allows the server to restart without waiting for
|
||||||
|
old connections to time out.
|
||||||
|
|
||||||
|
--detach::
|
||||||
|
Detach from the shell. Implies --syslog.
|
||||||
|
|
||||||
|
--pid-file=file::
|
||||||
|
Save the process id in 'file'.
|
||||||
|
|
||||||
<directory>::
|
<directory>::
|
||||||
A directory to add to the whitelist of allowed directories. Unless
|
A directory to add to the whitelist of allowed directories. Unless
|
||||||
--strict-paths is specified this will also include subdirectories
|
--strict-paths is specified this will also include subdirectories
|
||||||
|
@ -9,8 +9,9 @@ git-format-patch - Prepare patches for e-mail submission
|
|||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
[verse]
|
[verse]
|
||||||
'git-format-patch' [-n | -k] [-o <dir> | --stdout] [--attach]
|
'git-format-patch' [-n | -k] [-o <dir> | --stdout] [--attach] [--thread]
|
||||||
[-s | --signoff] [--diff-options] [--start-number <n>]
|
[-s | --signoff] [--diff-options] [--start-number <n>]
|
||||||
|
[--in-reply-to=Message-Id]
|
||||||
<since>[..<until>]
|
<since>[..<until>]
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
@ -35,6 +36,10 @@ they are created in the current working directory.
|
|||||||
If -n is specified, instead of "[PATCH] Subject", the first line
|
If -n is specified, instead of "[PATCH] Subject", the first line
|
||||||
is formatted as "[PATCH n/m] Subject".
|
is formatted as "[PATCH n/m] Subject".
|
||||||
|
|
||||||
|
If given --thread, git-format-patch will generate In-Reply-To and
|
||||||
|
References headers to make the second and subsequent patch mails appear
|
||||||
|
as replies to the first mail; this also generates a Message-Id header to
|
||||||
|
reference.
|
||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
-------
|
-------
|
||||||
@ -63,6 +68,15 @@ OPTIONS
|
|||||||
--attach::
|
--attach::
|
||||||
Create attachments instead of inlining patches.
|
Create attachments instead of inlining patches.
|
||||||
|
|
||||||
|
--thread::
|
||||||
|
Add In-Reply-To and References headers to make the second and
|
||||||
|
subsequent mails appear as replies to the first. Also generates
|
||||||
|
the Message-Id header to reference.
|
||||||
|
|
||||||
|
--in-reply-to=Message-Id::
|
||||||
|
Make the first mail (or all the mails with --no-thread) appear as a
|
||||||
|
reply to the given Message-Id, which avoids breaking threads to
|
||||||
|
provide a new patch series.
|
||||||
|
|
||||||
CONFIGURATION
|
CONFIGURATION
|
||||||
-------------
|
-------------
|
||||||
|
@ -8,7 +8,7 @@ git-http-fetch - downloads a remote git repository via HTTP
|
|||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
'git-http-fetch' [-c] [-t] [-a] [-d] [-v] [-w filename] [--recover] <commit> <url>
|
'git-http-fetch' [-c] [-t] [-a] [-d] [-v] [-w filename] [--recover] [--stdin] <commit> <url>
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
@ -33,6 +33,12 @@ commit-id::
|
|||||||
Writes the commit-id into the filename under $GIT_DIR/refs/<filename> on
|
Writes the commit-id into the filename under $GIT_DIR/refs/<filename> on
|
||||||
the local end after the transfer is complete.
|
the local end after the transfer is complete.
|
||||||
|
|
||||||
|
--stdin::
|
||||||
|
Instead of a commit id on the commandline (which is not expected in this
|
||||||
|
case), 'git-http-fetch' expects lines on stdin in the format
|
||||||
|
|
||||||
|
<commit-id>['\t'<filename-as-in--w>]
|
||||||
|
|
||||||
Author
|
Author
|
||||||
------
|
------
|
||||||
Written by Linus Torvalds <torvalds@osdl.org>
|
Written by Linus Torvalds <torvalds@osdl.org>
|
||||||
|
@ -29,6 +29,12 @@ OPTIONS
|
|||||||
Writes the commit-id into the filename under $GIT_DIR/refs/<filename> on
|
Writes the commit-id into the filename under $GIT_DIR/refs/<filename> on
|
||||||
the local end after the transfer is complete.
|
the local end after the transfer is complete.
|
||||||
|
|
||||||
|
--stdin::
|
||||||
|
Instead of a commit id on the commandline (which is not expected in this
|
||||||
|
case), 'git-local-fetch' expects lines on stdin in the format
|
||||||
|
|
||||||
|
<commit-id>['\t'<filename-as-in--w>]
|
||||||
|
|
||||||
Author
|
Author
|
||||||
------
|
------
|
||||||
Written by Junio C Hamano <junkio@cox.net>
|
Written by Junio C Hamano <junkio@cox.net>
|
||||||
|
@ -37,7 +37,20 @@ OPTIONS
|
|||||||
Instead of making a tar archive from local repository,
|
Instead of making a tar archive from local repository,
|
||||||
retrieve a tar archive from a remote repository.
|
retrieve a tar archive from a remote repository.
|
||||||
|
|
||||||
Examples
|
CONFIGURATION
|
||||||
|
-------------
|
||||||
|
By default, file and directories modes are set to 0666 or 0777. It is
|
||||||
|
possible to change this by setting the "umask" variable in the
|
||||||
|
repository configuration as follows :
|
||||||
|
|
||||||
|
[tar]
|
||||||
|
umask = 002 ;# group friendly
|
||||||
|
|
||||||
|
The special umask value "user" indicates that the user's current umask
|
||||||
|
will be used instead. The default value remains 0, which means world
|
||||||
|
readable/writable files and directories.
|
||||||
|
|
||||||
|
EXAMPLES
|
||||||
--------
|
--------
|
||||||
git tar-tree HEAD junk | (cd /var/tmp/ && tar xf -)::
|
git tar-tree HEAD junk | (cd /var/tmp/ && tar xf -)::
|
||||||
|
|
||||||
@ -58,6 +71,11 @@ git tar-tree --remote=example.com:git.git v1.4.0 >git-1.4.0.tar::
|
|||||||
|
|
||||||
Get a tarball v1.4.0 from example.com.
|
Get a tarball v1.4.0 from example.com.
|
||||||
|
|
||||||
|
git tar-tree HEAD:Documentation/ git-docs > git-1.4.0-docs.tar::
|
||||||
|
|
||||||
|
Put everything in the current head's Documentation/ directory
|
||||||
|
into 'git-1.4.0-docs.tar', with the prefix 'git-docs/'.
|
||||||
|
|
||||||
Author
|
Author
|
||||||
------
|
------
|
||||||
Written by Rene Scharfe.
|
Written by Rene Scharfe.
|
||||||
|
@ -8,7 +8,8 @@ git - the stupid content tracker
|
|||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
'git' [--version] [--exec-path[=GIT_EXEC_PATH]] [--help] COMMAND [ARGS]
|
'git' [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate]
|
||||||
|
[--bare] [--git-dir=GIT_DIR] [--help] COMMAND [ARGS]
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
@ -41,6 +42,15 @@ OPTIONS
|
|||||||
environment variable. If no path is given 'git' will print
|
environment variable. If no path is given 'git' will print
|
||||||
the current setting and then exit.
|
the current setting and then exit.
|
||||||
|
|
||||||
|
-p|--paginate::
|
||||||
|
Pipe all output into 'less' (or if set, $PAGER).
|
||||||
|
|
||||||
|
--git-dir=<path>::
|
||||||
|
Set the path to the repository. This can also be controlled by
|
||||||
|
setting the GIT_DIR environment variable.
|
||||||
|
|
||||||
|
--bare::
|
||||||
|
Same as --git-dir=`pwd`.
|
||||||
|
|
||||||
FURTHER DOCUMENTATION
|
FURTHER DOCUMENTATION
|
||||||
---------------------
|
---------------------
|
||||||
|
@ -10,20 +10,21 @@ to name the remote repository:
|
|||||||
- https://host.xz/path/to/repo.git/
|
- https://host.xz/path/to/repo.git/
|
||||||
- git://host.xz/path/to/repo.git/
|
- git://host.xz/path/to/repo.git/
|
||||||
- git://host.xz/~user/path/to/repo.git/
|
- git://host.xz/~user/path/to/repo.git/
|
||||||
- ssh://+++[user@+++]host.xz/path/to/repo.git/
|
- ssh://{startsb}user@{endsb}host.xz/path/to/repo.git/
|
||||||
- ssh://+++[user@+++]host.xz/~user/path/to/repo.git/
|
- ssh://{startsb}user@{endsb}host.xz/~user/path/to/repo.git/
|
||||||
- ssh://+++[user@+++]host.xz/~/path/to/repo.git
|
- ssh://{startsb}user@{endsb}host.xz/~/path/to/repo.git
|
||||||
===============================================================
|
===============================================================
|
||||||
|
|
||||||
SSH Is the default transport protocol and also supports an
|
SSH is the default transport protocol. You can optionally specify
|
||||||
scp-like syntax. Both syntaxes support username expansion,
|
which user to log-in as, and an alternate, scp-like syntax is also
|
||||||
|
supported. Both syntaxes support username expansion,
|
||||||
as does the native git protocol. The following three are
|
as does the native git protocol. The following three are
|
||||||
identical to the last three above, respectively:
|
identical to the last three above, respectively:
|
||||||
|
|
||||||
===============================================================
|
===============================================================
|
||||||
- host.xz:/path/to/repo.git/
|
- {startsb}user@{endsb}host.xz:/path/to/repo.git/
|
||||||
- host.xz:~user/path/to/repo.git/
|
- {startsb}user@{endsb}host.xz:~user/path/to/repo.git/
|
||||||
- host.xz:path/to/repo.git
|
- {startsb}user@{endsb}host.xz:path/to/repo.git
|
||||||
===============================================================
|
===============================================================
|
||||||
|
|
||||||
To sync with a local directory, use:
|
To sync with a local directory, use:
|
||||||
|
9
INSTALL
9
INSTALL
@ -13,6 +13,15 @@ that uses $prefix, the built results have some paths encoded,
|
|||||||
which are derived from $prefix, so "make all; make prefix=/usr
|
which are derived from $prefix, so "make all; make prefix=/usr
|
||||||
install" would not work.
|
install" would not work.
|
||||||
|
|
||||||
|
Alternatively you can use autoconf generated ./configure script to
|
||||||
|
set up install paths (via config.mak.autogen), so you can write instead
|
||||||
|
|
||||||
|
$ autoconf ;# as yourself if ./configure doesn't exist yet
|
||||||
|
$ ./configure --prefix=/usr ;# as yourself
|
||||||
|
$ make all doc ;# as yourself
|
||||||
|
# make install install-doc ;# as root
|
||||||
|
|
||||||
|
|
||||||
Issues of note:
|
Issues of note:
|
||||||
|
|
||||||
- git normally installs a helper script wrapper called "git", which
|
- git normally installs a helper script wrapper called "git", which
|
||||||
|
45
Makefile
45
Makefile
@ -37,6 +37,18 @@ all:
|
|||||||
# tests. These tests take up a significant amount of the total test time
|
# 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.
|
# but are not needed unless you plan to talk to SVN repos.
|
||||||
#
|
#
|
||||||
|
# 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 PPC_SHA1 environment variable when running make to make use of
|
# Define PPC_SHA1 environment variable when running make to make use of
|
||||||
# a bundled SHA1 routine optimized for PowerPC.
|
# a bundled SHA1 routine optimized for PowerPC.
|
||||||
#
|
#
|
||||||
@ -104,6 +116,8 @@ template_dir = $(prefix)/share/git-core/templates/
|
|||||||
GIT_PYTHON_DIR = $(prefix)/share/git-core/python
|
GIT_PYTHON_DIR = $(prefix)/share/git-core/python
|
||||||
# DESTDIR=
|
# DESTDIR=
|
||||||
|
|
||||||
|
export prefix bindir gitexecdir template_dir GIT_PYTHON_DIR
|
||||||
|
|
||||||
CC = gcc
|
CC = gcc
|
||||||
AR = ar
|
AR = ar
|
||||||
TAR = tar
|
TAR = tar
|
||||||
@ -137,7 +151,7 @@ SCRIPT_PERL = \
|
|||||||
git-archimport.perl git-cvsimport.perl git-relink.perl \
|
git-archimport.perl git-cvsimport.perl git-relink.perl \
|
||||||
git-shortlog.perl git-rerere.perl \
|
git-shortlog.perl git-rerere.perl \
|
||||||
git-annotate.perl git-cvsserver.perl \
|
git-annotate.perl git-cvsserver.perl \
|
||||||
git-svnimport.perl git-mv.perl git-cvsexportcommit.perl \
|
git-svnimport.perl git-cvsexportcommit.perl \
|
||||||
git-send-email.perl git-svn.perl
|
git-send-email.perl git-svn.perl
|
||||||
|
|
||||||
SCRIPT_PYTHON = \
|
SCRIPT_PYTHON = \
|
||||||
@ -179,7 +193,7 @@ BUILT_INS = git-log$X git-whatchanged$X git-show$X git-update-ref$X \
|
|||||||
git-read-tree$X git-commit-tree$X git-write-tree$X \
|
git-read-tree$X git-commit-tree$X git-write-tree$X \
|
||||||
git-apply$X git-show-branch$X git-diff-files$X git-update-index$X \
|
git-apply$X git-show-branch$X git-diff-files$X git-update-index$X \
|
||||||
git-diff-index$X git-diff-stages$X git-diff-tree$X git-cat-file$X \
|
git-diff-index$X git-diff-stages$X git-diff-tree$X git-cat-file$X \
|
||||||
git-fmt-merge-msg$X git-prune$X
|
git-fmt-merge-msg$X git-prune$X git-mv$X
|
||||||
|
|
||||||
# what 'all' will build and 'install' will install, in gitexecdir
|
# what 'all' will build and 'install' will install, in gitexecdir
|
||||||
ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS)
|
ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS)
|
||||||
@ -208,7 +222,7 @@ LIB_H = \
|
|||||||
blob.h cache.h commit.h csum-file.h delta.h \
|
blob.h cache.h commit.h csum-file.h delta.h \
|
||||||
diff.h object.h pack.h pkt-line.h quote.h refs.h \
|
diff.h object.h pack.h pkt-line.h quote.h refs.h \
|
||||||
run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h \
|
run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h \
|
||||||
tree-walk.h log-tree.h dir.h
|
tree-walk.h log-tree.h dir.h path-list.h unpack-trees.h
|
||||||
|
|
||||||
DIFF_OBJS = \
|
DIFF_OBJS = \
|
||||||
diff.o diff-lib.o diffcore-break.o diffcore-order.o \
|
diff.o diff-lib.o diffcore-break.o diffcore-order.o \
|
||||||
@ -223,7 +237,7 @@ LIB_OBJS = \
|
|||||||
server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \
|
server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \
|
||||||
tag.o tree.o usage.o config.o environment.o ctype.o copy.o \
|
tag.o tree.o usage.o config.o environment.o ctype.o copy.o \
|
||||||
fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \
|
fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \
|
||||||
alloc.o merge-file.o $(DIFF_OBJS)
|
alloc.o merge-file.o path-list.o unpack-trees.o $(DIFF_OBJS)
|
||||||
|
|
||||||
BUILTIN_OBJS = \
|
BUILTIN_OBJS = \
|
||||||
builtin-log.o builtin-help.o builtin-count.o builtin-diff.o builtin-push.o \
|
builtin-log.o builtin-help.o builtin-count.o builtin-diff.o builtin-push.o \
|
||||||
@ -235,7 +249,8 @@ BUILTIN_OBJS = \
|
|||||||
builtin-apply.o builtin-show-branch.o builtin-diff-files.o \
|
builtin-apply.o builtin-show-branch.o builtin-diff-files.o \
|
||||||
builtin-diff-index.o builtin-diff-stages.o builtin-diff-tree.o \
|
builtin-diff-index.o builtin-diff-stages.o builtin-diff-tree.o \
|
||||||
builtin-cat-file.o builtin-mailsplit.o builtin-stripspace.o \
|
builtin-cat-file.o builtin-mailsplit.o builtin-stripspace.o \
|
||||||
builtin-update-ref.o builtin-fmt-merge-msg.o builtin-prune.o
|
builtin-update-ref.o builtin-fmt-merge-msg.o builtin-prune.o \
|
||||||
|
builtin-mv.o
|
||||||
|
|
||||||
GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
|
GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
|
||||||
LIBS = $(GITLIBS) -lz
|
LIBS = $(GITLIBS) -lz
|
||||||
@ -251,21 +266,26 @@ LIBS = $(GITLIBS) -lz
|
|||||||
ifeq ($(uname_S),Linux)
|
ifeq ($(uname_S),Linux)
|
||||||
NO_STRLCPY = YesPlease
|
NO_STRLCPY = YesPlease
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(uname_S),GNU/kFreeBSD)
|
||||||
|
NO_STRLCPY = YesPlease
|
||||||
|
endif
|
||||||
ifeq ($(uname_S),Darwin)
|
ifeq ($(uname_S),Darwin)
|
||||||
NEEDS_SSL_WITH_CRYPTO = YesPlease
|
NEEDS_SSL_WITH_CRYPTO = YesPlease
|
||||||
NEEDS_LIBICONV = YesPlease
|
NEEDS_LIBICONV = YesPlease
|
||||||
NO_STRLCPY = YesPlease
|
NO_STRLCPY = YesPlease
|
||||||
## fink
|
ifndef NO_FINK
|
||||||
ifeq ($(shell test -d /sw/lib && echo y),y)
|
ifeq ($(shell test -d /sw/lib && echo y),y)
|
||||||
ALL_CFLAGS += -I/sw/include
|
ALL_CFLAGS += -I/sw/include
|
||||||
ALL_LDFLAGS += -L/sw/lib
|
ALL_LDFLAGS += -L/sw/lib
|
||||||
endif
|
endif
|
||||||
## darwinports
|
endif
|
||||||
|
ifndef NO_DARWIN_PORTS
|
||||||
ifeq ($(shell test -d /opt/local/lib && echo y),y)
|
ifeq ($(shell test -d /opt/local/lib && echo y),y)
|
||||||
ALL_CFLAGS += -I/opt/local/include
|
ALL_CFLAGS += -I/opt/local/include
|
||||||
ALL_LDFLAGS += -L/opt/local/lib
|
ALL_LDFLAGS += -L/opt/local/lib
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
ifeq ($(uname_S),SunOS)
|
ifeq ($(uname_S),SunOS)
|
||||||
NEEDS_SOCKET = YesPlease
|
NEEDS_SOCKET = YesPlease
|
||||||
NEEDS_NSL = YesPlease
|
NEEDS_NSL = YesPlease
|
||||||
@ -337,6 +357,7 @@ ifneq (,$(findstring arm,$(uname_M)))
|
|||||||
ARM_SHA1 = YesPlease
|
ARM_SHA1 = YesPlease
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
-include config.mak.autogen
|
||||||
-include config.mak
|
-include config.mak
|
||||||
|
|
||||||
ifdef WITH_OWN_SUBPROCESS_PY
|
ifdef WITH_OWN_SUBPROCESS_PY
|
||||||
@ -562,7 +583,7 @@ git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/gitweb.css
|
|||||||
-e '/@@GITWEB_CGI@@/d' \
|
-e '/@@GITWEB_CGI@@/d' \
|
||||||
-e '/@@GITWEB_CSS@@/r gitweb/gitweb.css' \
|
-e '/@@GITWEB_CSS@@/r gitweb/gitweb.css' \
|
||||||
-e '/@@GITWEB_CSS@@/d' \
|
-e '/@@GITWEB_CSS@@/d' \
|
||||||
$@.sh > $@+
|
$@.sh | sed "s|/usr/bin/git|$(bindir)/git|" > $@+
|
||||||
chmod +x $@+
|
chmod +x $@+
|
||||||
mv $@+ $@
|
mv $@+ $@
|
||||||
|
|
||||||
@ -599,6 +620,8 @@ $(SIMPLE_PROGRAMS) : git-%$X : %.o
|
|||||||
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
|
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
|
||||||
$(LIB_FILE) $(SIMPLE_LIB)
|
$(LIB_FILE) $(SIMPLE_LIB)
|
||||||
|
|
||||||
|
ssh-pull.o: ssh-fetch.c
|
||||||
|
ssh-push.o: ssh-upload.c
|
||||||
git-local-fetch$X: fetch.o
|
git-local-fetch$X: fetch.o
|
||||||
git-ssh-fetch$X: rsh.o fetch.o
|
git-ssh-fetch$X: rsh.o fetch.o
|
||||||
git-ssh-upload$X: rsh.o
|
git-ssh-upload$X: rsh.o
|
||||||
@ -745,8 +768,8 @@ dist-doc:
|
|||||||
rm -fr .doc-tmp-dir
|
rm -fr .doc-tmp-dir
|
||||||
mkdir .doc-tmp-dir .doc-tmp-dir/man1 .doc-tmp-dir/man7
|
mkdir .doc-tmp-dir .doc-tmp-dir/man1 .doc-tmp-dir/man7
|
||||||
$(MAKE) -C Documentation DESTDIR=./ \
|
$(MAKE) -C Documentation DESTDIR=./ \
|
||||||
man1=../.doc-tmp-dir/man1 \
|
man1dir=../.doc-tmp-dir/man1 \
|
||||||
man7=../.doc-tmp-dir/man7 \
|
man7dir=../.doc-tmp-dir/man7 \
|
||||||
install
|
install
|
||||||
cd .doc-tmp-dir && $(TAR) cf ../$(manpages).tar .
|
cd .doc-tmp-dir && $(TAR) cf ../$(manpages).tar .
|
||||||
gzip -n -9 -f $(manpages).tar
|
gzip -n -9 -f $(manpages).tar
|
||||||
@ -759,6 +782,8 @@ clean:
|
|||||||
$(LIB_FILE) $(XDIFF_LIB)
|
$(LIB_FILE) $(XDIFF_LIB)
|
||||||
rm -f $(ALL_PROGRAMS) $(BUILT_INS) git$X
|
rm -f $(ALL_PROGRAMS) $(BUILT_INS) git$X
|
||||||
rm -f *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags
|
rm -f *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags
|
||||||
|
rm -rf autom4te.cache
|
||||||
|
rm -f config.log config.mak.autogen configure config.status config.cache
|
||||||
rm -rf $(GIT_TARNAME) .doc-tmp-dir
|
rm -rf $(GIT_TARNAME) .doc-tmp-dir
|
||||||
rm -f $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz
|
rm -f $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz
|
||||||
rm -f $(htmldocs).tar.gz $(manpages).tar.gz
|
rm -f $(htmldocs).tar.gz $(manpages).tar.gz
|
||||||
|
2
blame.c
2
blame.c
@ -834,7 +834,7 @@ int main(int argc, const char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
init_revisions(&rev);
|
init_revisions(&rev, setup_git_directory());
|
||||||
rev.remove_empty_trees = 1;
|
rev.remove_empty_trees = 1;
|
||||||
rev.topo_order = 1;
|
rev.topo_order = 1;
|
||||||
rev.prune_fn = simplify_commit;
|
rev.prune_fn = simplify_commit;
|
||||||
|
@ -21,8 +21,7 @@ static void prune_directory(struct dir_struct *dir, const char **pathspec, int p
|
|||||||
|
|
||||||
for (specs = 0; pathspec[specs]; specs++)
|
for (specs = 0; pathspec[specs]; specs++)
|
||||||
/* nothing */;
|
/* nothing */;
|
||||||
seen = xmalloc(specs);
|
seen = xcalloc(specs, 1);
|
||||||
memset(seen, 0, specs);
|
|
||||||
|
|
||||||
src = dst = dir->entries;
|
src = dst = dir->entries;
|
||||||
i = dir->nr;
|
i = dir->nr;
|
||||||
@ -83,52 +82,12 @@ static void fill_directory(struct dir_struct *dir, const char **pathspec)
|
|||||||
prune_directory(dir, pathspec, baselen);
|
prune_directory(dir, pathspec, baselen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int add_file_to_index(const char *path, int verbose)
|
|
||||||
{
|
|
||||||
int size, namelen;
|
|
||||||
struct stat st;
|
|
||||||
struct cache_entry *ce;
|
|
||||||
|
|
||||||
if (lstat(path, &st))
|
|
||||||
die("%s: unable to stat (%s)", path, strerror(errno));
|
|
||||||
|
|
||||||
if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode))
|
|
||||||
die("%s: can only add regular files or symbolic links", path);
|
|
||||||
|
|
||||||
namelen = strlen(path);
|
|
||||||
size = cache_entry_size(namelen);
|
|
||||||
ce = xcalloc(1, size);
|
|
||||||
memcpy(ce->name, path, namelen);
|
|
||||||
ce->ce_flags = htons(namelen);
|
|
||||||
fill_stat_cache_info(ce, &st);
|
|
||||||
|
|
||||||
ce->ce_mode = create_ce_mode(st.st_mode);
|
|
||||||
if (!trust_executable_bit) {
|
|
||||||
/* If there is an existing entry, pick the mode bits
|
|
||||||
* from it.
|
|
||||||
*/
|
|
||||||
int pos = cache_name_pos(path, namelen);
|
|
||||||
if (pos >= 0)
|
|
||||||
ce->ce_mode = active_cache[pos]->ce_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index_path(ce->sha1, path, &st, 1))
|
|
||||||
die("unable to index file %s", path);
|
|
||||||
if (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD))
|
|
||||||
die("unable to add %s to index",path);
|
|
||||||
if (verbose)
|
|
||||||
printf("add '%s'\n", path);
|
|
||||||
cache_tree_invalidate_path(active_cache_tree, path);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct lock_file lock_file;
|
static struct lock_file lock_file;
|
||||||
|
|
||||||
int cmd_add(int argc, const char **argv, char **envp)
|
int cmd_add(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int i, newfd;
|
int i, newfd;
|
||||||
int verbose = 0, show_only = 0;
|
int verbose = 0, show_only = 0;
|
||||||
const char *prefix = setup_git_directory();
|
|
||||||
const char **pathspec;
|
const char **pathspec;
|
||||||
struct dir_struct dir;
|
struct dir_struct dir;
|
||||||
|
|
||||||
@ -160,7 +119,6 @@ int cmd_add(int argc, const char **argv, char **envp)
|
|||||||
}
|
}
|
||||||
die(builtin_add_usage);
|
die(builtin_add_usage);
|
||||||
}
|
}
|
||||||
git_config(git_default_config);
|
|
||||||
pathspec = get_pathspec(prefix, argv + i);
|
pathspec = get_pathspec(prefix, argv + i);
|
||||||
|
|
||||||
fill_directory(&dir, pathspec);
|
fill_directory(&dir, pathspec);
|
||||||
|
137
builtin-apply.c
137
builtin-apply.c
@ -120,7 +120,7 @@ struct fragment {
|
|||||||
struct patch {
|
struct patch {
|
||||||
char *new_name, *old_name, *def_name;
|
char *new_name, *old_name, *def_name;
|
||||||
unsigned int old_mode, new_mode;
|
unsigned int old_mode, new_mode;
|
||||||
int is_rename, is_copy, is_new, is_delete, is_binary;
|
int is_rename, is_copy, is_new, is_delete, is_binary, is_reverse;
|
||||||
#define BINARY_DELTA_DEFLATED 1
|
#define BINARY_DELTA_DEFLATED 1
|
||||||
#define BINARY_LITERAL_DEFLATED 2
|
#define BINARY_LITERAL_DEFLATED 2
|
||||||
unsigned long deflate_origlen;
|
unsigned long deflate_origlen;
|
||||||
@ -1119,6 +1119,34 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch)
|
|||||||
return offset + hdrsize + patchsize;
|
return offset + hdrsize + patchsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define swap(a,b) myswap((a),(b),sizeof(a))
|
||||||
|
|
||||||
|
#define myswap(a, b, size) do { \
|
||||||
|
unsigned char mytmp[size]; \
|
||||||
|
memcpy(mytmp, &a, size); \
|
||||||
|
memcpy(&a, &b, size); \
|
||||||
|
memcpy(&b, mytmp, size); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static void reverse_patches(struct patch *p)
|
||||||
|
{
|
||||||
|
for (; p; p = p->next) {
|
||||||
|
struct fragment *frag = p->fragments;
|
||||||
|
|
||||||
|
swap(p->new_name, p->old_name);
|
||||||
|
swap(p->new_mode, p->old_mode);
|
||||||
|
swap(p->is_new, p->is_delete);
|
||||||
|
swap(p->lines_added, p->lines_deleted);
|
||||||
|
swap(p->old_sha1_prefix, p->new_sha1_prefix);
|
||||||
|
|
||||||
|
for (; frag; frag = frag->next) {
|
||||||
|
swap(frag->newpos, frag->oldpos);
|
||||||
|
swap(frag->newlines, frag->oldlines);
|
||||||
|
}
|
||||||
|
p->is_reverse = !p->is_reverse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const char pluses[] = "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
|
static const char pluses[] = "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
|
||||||
static const char minuses[]= "----------------------------------------------------------------------";
|
static const char minuses[]= "----------------------------------------------------------------------";
|
||||||
|
|
||||||
@ -1336,7 +1364,7 @@ static int apply_line(char *output, const char *patch, int plen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag,
|
static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag,
|
||||||
int inaccurate_eof)
|
int reverse, int inaccurate_eof)
|
||||||
{
|
{
|
||||||
int match_beginning, match_end;
|
int match_beginning, match_end;
|
||||||
char *buf = desc->buffer;
|
char *buf = desc->buffer;
|
||||||
@ -1350,6 +1378,7 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag,
|
|||||||
int pos, lines;
|
int pos, lines;
|
||||||
|
|
||||||
while (size > 0) {
|
while (size > 0) {
|
||||||
|
char first;
|
||||||
int len = linelen(patch, size);
|
int len = linelen(patch, size);
|
||||||
int plen;
|
int plen;
|
||||||
|
|
||||||
@ -1366,16 +1395,23 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag,
|
|||||||
plen = len-1;
|
plen = len-1;
|
||||||
if (len < size && patch[len] == '\\')
|
if (len < size && patch[len] == '\\')
|
||||||
plen--;
|
plen--;
|
||||||
switch (*patch) {
|
first = *patch;
|
||||||
|
if (reverse) {
|
||||||
|
if (first == '-')
|
||||||
|
first = '+';
|
||||||
|
else if (first == '+')
|
||||||
|
first = '-';
|
||||||
|
}
|
||||||
|
switch (first) {
|
||||||
case ' ':
|
case ' ':
|
||||||
case '-':
|
case '-':
|
||||||
memcpy(old + oldsize, patch + 1, plen);
|
memcpy(old + oldsize, patch + 1, plen);
|
||||||
oldsize += plen;
|
oldsize += plen;
|
||||||
if (*patch == '-')
|
if (first == '-')
|
||||||
break;
|
break;
|
||||||
/* Fall-through for ' ' */
|
/* Fall-through for ' ' */
|
||||||
case '+':
|
case '+':
|
||||||
if (*patch != '+' || !no_add)
|
if (first != '+' || !no_add)
|
||||||
newsize += apply_line(new + newsize, patch,
|
newsize += apply_line(new + newsize, patch,
|
||||||
plen);
|
plen);
|
||||||
break;
|
break;
|
||||||
@ -1499,6 +1535,12 @@ static int apply_binary_fragment(struct buffer_desc *desc, struct patch *patch)
|
|||||||
void *data;
|
void *data;
|
||||||
void *result;
|
void *result;
|
||||||
|
|
||||||
|
/* Binary patch is irreversible */
|
||||||
|
if (patch->is_reverse)
|
||||||
|
return error("cannot reverse-apply a binary patch to '%s'",
|
||||||
|
patch->new_name
|
||||||
|
? patch->new_name : patch->old_name);
|
||||||
|
|
||||||
data = inflate_it(fragment->patch, fragment->size,
|
data = inflate_it(fragment->patch, fragment->size,
|
||||||
patch->deflate_origlen);
|
patch->deflate_origlen);
|
||||||
if (!data)
|
if (!data)
|
||||||
@ -1615,7 +1657,8 @@ static int apply_fragments(struct buffer_desc *desc, struct patch *patch)
|
|||||||
return apply_binary(desc, patch);
|
return apply_binary(desc, patch);
|
||||||
|
|
||||||
while (frag) {
|
while (frag) {
|
||||||
if (apply_one_fragment(desc, frag, patch->inaccurate_eof) < 0)
|
if (apply_one_fragment(desc, frag, patch->is_reverse,
|
||||||
|
patch->inaccurate_eof) < 0)
|
||||||
return error("patch failed: %s:%ld",
|
return error("patch failed: %s:%ld",
|
||||||
name, frag->oldpos);
|
name, frag->oldpos);
|
||||||
frag = frag->next;
|
frag = frag->next;
|
||||||
@ -1664,13 +1707,14 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int check_patch(struct patch *patch)
|
static int check_patch(struct patch *patch, struct patch *prev_patch)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
const char *old_name = patch->old_name;
|
const char *old_name = patch->old_name;
|
||||||
const char *new_name = patch->new_name;
|
const char *new_name = patch->new_name;
|
||||||
const char *name = old_name ? old_name : new_name;
|
const char *name = old_name ? old_name : new_name;
|
||||||
struct cache_entry *ce = NULL;
|
struct cache_entry *ce = NULL;
|
||||||
|
int ok_if_exists;
|
||||||
|
|
||||||
if (old_name) {
|
if (old_name) {
|
||||||
int changed = 0;
|
int changed = 0;
|
||||||
@ -1728,13 +1772,33 @@ static int check_patch(struct patch *patch)
|
|||||||
old_name, st_mode, patch->old_mode);
|
old_name, st_mode, patch->old_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (new_name && prev_patch && prev_patch->is_delete &&
|
||||||
|
!strcmp(prev_patch->old_name, new_name))
|
||||||
|
/* A type-change diff is always split into a patch to
|
||||||
|
* delete old, immediately followed by a patch to
|
||||||
|
* create new (see diff.c::run_diff()); in such a case
|
||||||
|
* it is Ok that the entry to be deleted by the
|
||||||
|
* previous patch is still in the working tree and in
|
||||||
|
* the index.
|
||||||
|
*/
|
||||||
|
ok_if_exists = 1;
|
||||||
|
else
|
||||||
|
ok_if_exists = 0;
|
||||||
|
|
||||||
if (new_name && (patch->is_new | patch->is_rename | patch->is_copy)) {
|
if (new_name && (patch->is_new | patch->is_rename | patch->is_copy)) {
|
||||||
if (check_index && cache_name_pos(new_name, strlen(new_name)) >= 0)
|
if (check_index &&
|
||||||
|
cache_name_pos(new_name, strlen(new_name)) >= 0 &&
|
||||||
|
!ok_if_exists)
|
||||||
return error("%s: already exists in index", new_name);
|
return error("%s: already exists in index", new_name);
|
||||||
if (!cached) {
|
if (!cached) {
|
||||||
if (!lstat(new_name, &st))
|
struct stat nst;
|
||||||
|
if (!lstat(new_name, &nst)) {
|
||||||
|
if (S_ISDIR(nst.st_mode) || ok_if_exists)
|
||||||
|
; /* ok */
|
||||||
|
else
|
||||||
return error("%s: already exists in working directory", new_name);
|
return error("%s: already exists in working directory", new_name);
|
||||||
if (errno != ENOENT)
|
}
|
||||||
|
else if ((errno != ENOENT) && (errno != ENOTDIR))
|
||||||
return error("%s: %s", new_name, strerror(errno));
|
return error("%s: %s", new_name, strerror(errno));
|
||||||
}
|
}
|
||||||
if (!patch->new_mode) {
|
if (!patch->new_mode) {
|
||||||
@ -1762,10 +1826,13 @@ static int check_patch(struct patch *patch)
|
|||||||
|
|
||||||
static int check_patch_list(struct patch *patch)
|
static int check_patch_list(struct patch *patch)
|
||||||
{
|
{
|
||||||
|
struct patch *prev_patch = NULL;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
for (;patch ; patch = patch->next)
|
for (prev_patch = NULL; patch ; patch = patch->next) {
|
||||||
error |= check_patch(patch);
|
error |= check_patch(patch, prev_patch);
|
||||||
|
prev_patch = patch;
|
||||||
|
}
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2010,6 +2077,16 @@ static void create_one_file(char *path, unsigned mode, const char *buf, unsigned
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (errno == EEXIST || errno == EACCES) {
|
||||||
|
/* We may be trying to create a file where a directory
|
||||||
|
* used to be.
|
||||||
|
*/
|
||||||
|
struct stat st;
|
||||||
|
errno = 0;
|
||||||
|
if (!lstat(path, &st) && S_ISDIR(st.st_mode) && !rmdir(path))
|
||||||
|
errno = EEXIST;
|
||||||
|
}
|
||||||
|
|
||||||
if (errno == EEXIST) {
|
if (errno == EEXIST) {
|
||||||
unsigned int nr = getpid();
|
unsigned int nr = getpid();
|
||||||
|
|
||||||
@ -2044,13 +2121,16 @@ static void create_file(struct patch *patch)
|
|||||||
cache_tree_invalidate_path(active_cache_tree, path);
|
cache_tree_invalidate_path(active_cache_tree, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_out_one_result(struct patch *patch)
|
/* phase zero is to remove, phase one is to create */
|
||||||
|
static void write_out_one_result(struct patch *patch, int phase)
|
||||||
{
|
{
|
||||||
if (patch->is_delete > 0) {
|
if (patch->is_delete > 0) {
|
||||||
|
if (phase == 0)
|
||||||
remove_file(patch);
|
remove_file(patch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (patch->is_new > 0 || patch->is_copy) {
|
if (patch->is_new > 0 || patch->is_copy) {
|
||||||
|
if (phase == 1)
|
||||||
create_file(patch);
|
create_file(patch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2058,18 +2138,25 @@ static void write_out_one_result(struct patch *patch)
|
|||||||
* Rename or modification boils down to the same
|
* Rename or modification boils down to the same
|
||||||
* thing: remove the old, write the new
|
* thing: remove the old, write the new
|
||||||
*/
|
*/
|
||||||
|
if (phase == 0)
|
||||||
remove_file(patch);
|
remove_file(patch);
|
||||||
|
if (phase == 1)
|
||||||
create_file(patch);
|
create_file(patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_out_results(struct patch *list, int skipped_patch)
|
static void write_out_results(struct patch *list, int skipped_patch)
|
||||||
{
|
{
|
||||||
|
int phase;
|
||||||
|
|
||||||
if (!list && !skipped_patch)
|
if (!list && !skipped_patch)
|
||||||
die("No changes");
|
die("No changes");
|
||||||
|
|
||||||
while (list) {
|
for (phase = 0; phase < 2; phase++) {
|
||||||
write_out_one_result(list);
|
struct patch *l = list;
|
||||||
list = list->next;
|
while (l) {
|
||||||
|
write_out_one_result(l, phase);
|
||||||
|
l = l->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2098,7 +2185,8 @@ static int use_patch(struct patch *p)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_patch(int fd, const char *filename, int inaccurate_eof)
|
static int apply_patch(int fd, const char *filename,
|
||||||
|
int reverse, int inaccurate_eof)
|
||||||
{
|
{
|
||||||
unsigned long offset, size;
|
unsigned long offset, size;
|
||||||
char *buffer = read_patch_file(fd, &size);
|
char *buffer = read_patch_file(fd, &size);
|
||||||
@ -2118,6 +2206,8 @@ static int apply_patch(int fd, const char *filename, int inaccurate_eof)
|
|||||||
nr = parse_chunk(buffer + offset, size, patch);
|
nr = parse_chunk(buffer + offset, size, patch);
|
||||||
if (nr < 0)
|
if (nr < 0)
|
||||||
break;
|
break;
|
||||||
|
if (reverse)
|
||||||
|
reverse_patches(patch);
|
||||||
if (use_patch(patch)) {
|
if (use_patch(patch)) {
|
||||||
patch_stats(patch);
|
patch_stats(patch);
|
||||||
*listp = patch;
|
*listp = patch;
|
||||||
@ -2178,10 +2268,11 @@ static int git_apply_config(const char *var, const char *value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int cmd_apply(int argc, const char **argv, char **envp)
|
int cmd_apply(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int read_stdin = 1;
|
int read_stdin = 1;
|
||||||
|
int reverse = 0;
|
||||||
int inaccurate_eof = 0;
|
int inaccurate_eof = 0;
|
||||||
|
|
||||||
const char *whitespace_option = NULL;
|
const char *whitespace_option = NULL;
|
||||||
@ -2192,7 +2283,7 @@ int cmd_apply(int argc, const char **argv, char **envp)
|
|||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (!strcmp(arg, "-")) {
|
if (!strcmp(arg, "-")) {
|
||||||
apply_patch(0, "<stdin>", inaccurate_eof);
|
apply_patch(0, "<stdin>", reverse, inaccurate_eof);
|
||||||
read_stdin = 0;
|
read_stdin = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2269,6 +2360,10 @@ int cmd_apply(int argc, const char **argv, char **envp)
|
|||||||
parse_whitespace_option(arg + 13);
|
parse_whitespace_option(arg + 13);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!strcmp(arg, "-R") || !strcmp(arg, "--reverse")) {
|
||||||
|
reverse = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!strcmp(arg, "--inaccurate-eof")) {
|
if (!strcmp(arg, "--inaccurate-eof")) {
|
||||||
inaccurate_eof = 1;
|
inaccurate_eof = 1;
|
||||||
continue;
|
continue;
|
||||||
@ -2289,12 +2384,12 @@ int cmd_apply(int argc, const char **argv, char **envp)
|
|||||||
usage(apply_usage);
|
usage(apply_usage);
|
||||||
read_stdin = 0;
|
read_stdin = 0;
|
||||||
set_default_whitespace_mode(whitespace_option);
|
set_default_whitespace_mode(whitespace_option);
|
||||||
apply_patch(fd, arg, inaccurate_eof);
|
apply_patch(fd, arg, reverse, inaccurate_eof);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
set_default_whitespace_mode(whitespace_option);
|
set_default_whitespace_mode(whitespace_option);
|
||||||
if (read_stdin)
|
if (read_stdin)
|
||||||
apply_patch(0, "<stdin>", inaccurate_eof);
|
apply_patch(0, "<stdin>", reverse, inaccurate_eof);
|
||||||
if (whitespace_error) {
|
if (whitespace_error) {
|
||||||
if (squelch_whitespace_errors &&
|
if (squelch_whitespace_errors &&
|
||||||
squelch_whitespace_errors < whitespace_error) {
|
squelch_whitespace_errors < whitespace_error) {
|
||||||
|
@ -94,7 +94,7 @@ static int pprint_tag(const unsigned char *sha1, const char *buf, unsigned long
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_cat_file(int argc, const char **argv, char **envp)
|
int cmd_cat_file(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
char type[20];
|
char type[20];
|
||||||
@ -102,7 +102,6 @@ int cmd_cat_file(int argc, const char **argv, char **envp)
|
|||||||
unsigned long size;
|
unsigned long size;
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
setup_git_directory();
|
|
||||||
git_config(git_default_config);
|
git_config(git_default_config);
|
||||||
if (argc != 3)
|
if (argc != 3)
|
||||||
usage("git-cat-file [-t|-s|-e|-p|<type>] <sha1>");
|
usage("git-cat-file [-t|-s|-e|-p|<type>] <sha1>");
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include "refs.h"
|
#include "refs.h"
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
|
|
||||||
int cmd_check_ref_format(int argc, const char **argv, char **envp)
|
int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
if (argc != 2)
|
if (argc != 2)
|
||||||
usage("git check-ref-format refname");
|
usage("git check-ref-format refname");
|
||||||
|
@ -77,7 +77,7 @@ static int new_parent(int idx)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_commit_tree(int argc, const char **argv, char **envp)
|
int cmd_commit_tree(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int parents = 0;
|
int parents = 0;
|
||||||
@ -88,8 +88,6 @@ int cmd_commit_tree(int argc, const char **argv, char **envp)
|
|||||||
unsigned int size;
|
unsigned int size;
|
||||||
|
|
||||||
setup_ident();
|
setup_ident();
|
||||||
setup_git_directory();
|
|
||||||
|
|
||||||
git_config(git_default_config);
|
git_config(git_default_config);
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
|
@ -67,7 +67,7 @@ static void count_objects(DIR *d, char *path, int len, int verbose,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_count_objects(int ac, const char **av, char **ep)
|
int cmd_count_objects(int ac, const char **av, const char *prefix)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int verbose = 0;
|
int verbose = 0;
|
||||||
|
@ -13,13 +13,13 @@ static const char diff_files_usage[] =
|
|||||||
"git-diff-files [-q] [-0/-1/2/3 |-c|--cc] [<common diff options>] [<path>...]"
|
"git-diff-files [-q] [-0/-1/2/3 |-c|--cc] [<common diff options>] [<path>...]"
|
||||||
COMMON_DIFF_OPTIONS_HELP;
|
COMMON_DIFF_OPTIONS_HELP;
|
||||||
|
|
||||||
int cmd_diff_files(int argc, const char **argv, char **envp)
|
int cmd_diff_files(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
struct rev_info rev;
|
struct rev_info rev;
|
||||||
int silent = 0;
|
int silent = 0;
|
||||||
|
|
||||||
|
init_revisions(&rev, prefix);
|
||||||
git_config(git_default_config); /* no "diff" UI options */
|
git_config(git_default_config); /* no "diff" UI options */
|
||||||
init_revisions(&rev);
|
|
||||||
rev.abbrev = 0;
|
rev.abbrev = 0;
|
||||||
|
|
||||||
argc = setup_revisions(argc, argv, &rev, NULL);
|
argc = setup_revisions(argc, argv, &rev, NULL);
|
||||||
|
@ -9,14 +9,14 @@ static const char diff_cache_usage[] =
|
|||||||
"[<common diff options>] <tree-ish> [<path>...]"
|
"[<common diff options>] <tree-ish> [<path>...]"
|
||||||
COMMON_DIFF_OPTIONS_HELP;
|
COMMON_DIFF_OPTIONS_HELP;
|
||||||
|
|
||||||
int cmd_diff_index(int argc, const char **argv, char **envp)
|
int cmd_diff_index(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
struct rev_info rev;
|
struct rev_info rev;
|
||||||
int cached = 0;
|
int cached = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
init_revisions(&rev, prefix);
|
||||||
git_config(git_default_config); /* no "diff" UI options */
|
git_config(git_default_config); /* no "diff" UI options */
|
||||||
init_revisions(&rev);
|
|
||||||
rev.abbrev = 0;
|
rev.abbrev = 0;
|
||||||
|
|
||||||
argc = setup_revisions(argc, argv, &rev, NULL);
|
argc = setup_revisions(argc, argv, &rev, NULL);
|
||||||
|
@ -55,10 +55,9 @@ static void diff_stages(int stage1, int stage2, const char **pathspec)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_diff_stages(int ac, const char **av, char **envp)
|
int cmd_diff_stages(int ac, const char **av, const char *prefix)
|
||||||
{
|
{
|
||||||
int stage1, stage2;
|
int stage1, stage2;
|
||||||
const char *prefix = setup_git_directory();
|
|
||||||
const char **pathspec = NULL;
|
const char **pathspec = NULL;
|
||||||
|
|
||||||
git_config(git_default_config); /* no "diff" UI options */
|
git_config(git_default_config); /* no "diff" UI options */
|
||||||
|
@ -59,7 +59,7 @@ static const char diff_tree_usage[] =
|
|||||||
" --root include the initial commit as diff against /dev/null\n"
|
" --root include the initial commit as diff against /dev/null\n"
|
||||||
COMMON_DIFF_OPTIONS_HELP;
|
COMMON_DIFF_OPTIONS_HELP;
|
||||||
|
|
||||||
int cmd_diff_tree(int argc, const char **argv, char **envp)
|
int cmd_diff_tree(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int nr_sha1;
|
int nr_sha1;
|
||||||
char line[1000];
|
char line[1000];
|
||||||
@ -67,9 +67,9 @@ int cmd_diff_tree(int argc, const char **argv, char **envp)
|
|||||||
static struct rev_info *opt = &log_tree_opt;
|
static struct rev_info *opt = &log_tree_opt;
|
||||||
int read_stdin = 0;
|
int read_stdin = 0;
|
||||||
|
|
||||||
|
init_revisions(opt, prefix);
|
||||||
git_config(git_default_config); /* no "diff" UI options */
|
git_config(git_default_config); /* no "diff" UI options */
|
||||||
nr_sha1 = 0;
|
nr_sha1 = 0;
|
||||||
init_revisions(opt);
|
|
||||||
opt->abbrev = 0;
|
opt->abbrev = 0;
|
||||||
opt->diff = 1;
|
opt->diff = 1;
|
||||||
argc = setup_revisions(argc, argv, opt, NULL);
|
argc = setup_revisions(argc, argv, opt, NULL);
|
||||||
|
@ -221,7 +221,7 @@ void add_head(struct rev_info *revs)
|
|||||||
add_pending_object(revs, obj, "HEAD");
|
add_pending_object(revs, obj, "HEAD");
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_diff(int argc, const char **argv, char **envp)
|
int cmd_diff(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct rev_info rev;
|
struct rev_info rev;
|
||||||
@ -251,7 +251,7 @@ int cmd_diff(int argc, const char **argv, char **envp)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
git_config(git_diff_ui_config);
|
git_config(git_diff_ui_config);
|
||||||
init_revisions(&rev);
|
init_revisions(&rev, prefix);
|
||||||
|
|
||||||
argc = setup_revisions(argc, argv, &rev, NULL);
|
argc = setup_revisions(argc, argv, &rev, NULL);
|
||||||
if (!rev.diffopt.output_format) {
|
if (!rev.diffopt.output_format) {
|
||||||
@ -346,7 +346,15 @@ int cmd_diff(int argc, const char **argv, char **envp)
|
|||||||
return builtin_diff_index(&rev, argc, argv);
|
return builtin_diff_index(&rev, argc, argv);
|
||||||
else if (ents == 2)
|
else if (ents == 2)
|
||||||
return builtin_diff_tree(&rev, argc, argv, ent);
|
return builtin_diff_tree(&rev, argc, argv, ent);
|
||||||
|
else if ((ents == 3) && (ent[0].item->flags & UNINTERESTING)) {
|
||||||
|
/* diff A...B where there is one sane merge base between
|
||||||
|
* A and B. We have ent[0] == merge-base, ent[1] == A,
|
||||||
|
* and ent[2] == B. Show diff between the base and B.
|
||||||
|
*/
|
||||||
|
return builtin_diff_tree(&rev, argc, argv, ent);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return builtin_diff_combined(&rev, argc, argv, ent, ents);
|
return builtin_diff_combined(&rev, argc, argv,
|
||||||
|
ent, ents);
|
||||||
usage(builtin_diff_usage);
|
usage(builtin_diff_usage);
|
||||||
}
|
}
|
||||||
|
@ -242,7 +242,7 @@ static void shortlog(const char *name, unsigned char *sha1,
|
|||||||
free_list(&subjects);
|
free_list(&subjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_fmt_merge_msg(int argc, char **argv, char **envp)
|
int cmd_fmt_merge_msg(int argc, char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int limit = 20, i = 0;
|
int limit = 20, i = 0;
|
||||||
char line[1024];
|
char line[1024];
|
||||||
@ -342,7 +342,7 @@ int cmd_fmt_merge_msg(int argc, char **argv, char **envp)
|
|||||||
struct rev_info rev;
|
struct rev_info rev;
|
||||||
|
|
||||||
head = lookup_commit(head_sha1);
|
head = lookup_commit(head_sha1);
|
||||||
init_revisions(&rev);
|
init_revisions(&rev, prefix);
|
||||||
rev.commit_format = CMIT_FMT_ONELINE;
|
rev.commit_format = CMIT_FMT_ONELINE;
|
||||||
rev.ignore_merges = 1;
|
rev.ignore_merges = 1;
|
||||||
rev.limited = 1;
|
rev.limited = 1;
|
||||||
|
@ -919,14 +919,13 @@ static const char emsg_missing_context_len[] =
|
|||||||
static const char emsg_missing_argument[] =
|
static const char emsg_missing_argument[] =
|
||||||
"option requires an argument -%s";
|
"option requires an argument -%s";
|
||||||
|
|
||||||
int cmd_grep(int argc, const char **argv, char **envp)
|
int cmd_grep(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int hit = 0;
|
int hit = 0;
|
||||||
int cached = 0;
|
int cached = 0;
|
||||||
int seen_dashdash = 0;
|
int seen_dashdash = 0;
|
||||||
struct grep_opt opt;
|
struct grep_opt opt;
|
||||||
struct object_array list = { 0, 0, NULL };
|
struct object_array list = { 0, 0, NULL };
|
||||||
const char *prefix = setup_git_directory();
|
|
||||||
const char **paths = NULL;
|
const char **paths = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -221,15 +221,15 @@ static void show_man_page(const char *git_cmd)
|
|||||||
execlp("man", "man", page, NULL);
|
execlp("man", "man", page, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_version(int argc, const char **argv, char **envp)
|
int cmd_version(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
printf("git version %s\n", git_version_string);
|
printf("git version %s\n", git_version_string);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_help(int argc, const char **argv, char **envp)
|
int cmd_help(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
const char *help_cmd = argv[1];
|
const char *help_cmd = argc > 1 ? argv[1] : NULL;
|
||||||
if (!help_cmd)
|
if (!help_cmd)
|
||||||
cmd_usage(0, git_exec_path(), NULL);
|
cmd_usage(0, git_exec_path(), NULL);
|
||||||
else if (!strcmp(help_cmd, "--all") || !strcmp(help_cmd, "-a"))
|
else if (!strcmp(help_cmd, "--all") || !strcmp(help_cmd, "-a"))
|
||||||
|
@ -250,7 +250,7 @@ static const char init_db_usage[] =
|
|||||||
* On the other hand, it might just make lookup slower and messier. You
|
* On the other hand, it might just make lookup slower and messier. You
|
||||||
* be the judge. The default case is to have one DB per managed directory.
|
* be the judge. The default case is to have one DB per managed directory.
|
||||||
*/
|
*/
|
||||||
int cmd_init_db(int argc, const char **argv, char **envp)
|
int cmd_init_db(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
const char *git_dir;
|
const char *git_dir;
|
||||||
const char *sha1_dir;
|
const char *sha1_dir;
|
||||||
|
@ -10,11 +10,13 @@
|
|||||||
#include "revision.h"
|
#include "revision.h"
|
||||||
#include "log-tree.h"
|
#include "log-tree.h"
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
/* this is in builtin-diff.c */
|
/* this is in builtin-diff.c */
|
||||||
void add_head(struct rev_info *revs);
|
void add_head(struct rev_info *revs);
|
||||||
|
|
||||||
static void cmd_log_init(int argc, const char **argv, char **envp,
|
static void cmd_log_init(int argc, const char **argv, const char *prefix,
|
||||||
struct rev_info *rev)
|
struct rev_info *rev)
|
||||||
{
|
{
|
||||||
rev->abbrev = DEFAULT_ABBREV;
|
rev->abbrev = DEFAULT_ABBREV;
|
||||||
@ -43,27 +45,27 @@ static int cmd_log_walk(struct rev_info *rev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_whatchanged(int argc, const char **argv, char **envp)
|
int cmd_whatchanged(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
struct rev_info rev;
|
struct rev_info rev;
|
||||||
|
|
||||||
git_config(git_diff_ui_config);
|
git_config(git_diff_ui_config);
|
||||||
init_revisions(&rev);
|
init_revisions(&rev, prefix);
|
||||||
rev.diff = 1;
|
rev.diff = 1;
|
||||||
rev.diffopt.recursive = 1;
|
rev.diffopt.recursive = 1;
|
||||||
rev.simplify_history = 0;
|
rev.simplify_history = 0;
|
||||||
cmd_log_init(argc, argv, envp, &rev);
|
cmd_log_init(argc, argv, prefix, &rev);
|
||||||
if (!rev.diffopt.output_format)
|
if (!rev.diffopt.output_format)
|
||||||
rev.diffopt.output_format = DIFF_FORMAT_RAW;
|
rev.diffopt.output_format = DIFF_FORMAT_RAW;
|
||||||
return cmd_log_walk(&rev);
|
return cmd_log_walk(&rev);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_show(int argc, const char **argv, char **envp)
|
int cmd_show(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
struct rev_info rev;
|
struct rev_info rev;
|
||||||
|
|
||||||
git_config(git_diff_ui_config);
|
git_config(git_diff_ui_config);
|
||||||
init_revisions(&rev);
|
init_revisions(&rev, prefix);
|
||||||
rev.diff = 1;
|
rev.diff = 1;
|
||||||
rev.diffopt.recursive = 1;
|
rev.diffopt.recursive = 1;
|
||||||
rev.combine_merges = 1;
|
rev.combine_merges = 1;
|
||||||
@ -71,18 +73,18 @@ int cmd_show(int argc, const char **argv, char **envp)
|
|||||||
rev.always_show_header = 1;
|
rev.always_show_header = 1;
|
||||||
rev.ignore_merges = 0;
|
rev.ignore_merges = 0;
|
||||||
rev.no_walk = 1;
|
rev.no_walk = 1;
|
||||||
cmd_log_init(argc, argv, envp, &rev);
|
cmd_log_init(argc, argv, prefix, &rev);
|
||||||
return cmd_log_walk(&rev);
|
return cmd_log_walk(&rev);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_log(int argc, const char **argv, char **envp)
|
int cmd_log(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
struct rev_info rev;
|
struct rev_info rev;
|
||||||
|
|
||||||
git_config(git_diff_ui_config);
|
git_config(git_diff_ui_config);
|
||||||
init_revisions(&rev);
|
init_revisions(&rev, prefix);
|
||||||
rev.always_show_header = 1;
|
rev.always_show_header = 1;
|
||||||
cmd_log_init(argc, argv, envp, &rev);
|
cmd_log_init(argc, argv, prefix, &rev);
|
||||||
return cmd_log_walk(&rev);
|
return cmd_log_walk(&rev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,7 +178,7 @@ static int get_patch_id(struct commit *commit, struct diff_options *options,
|
|||||||
return diff_flush_patch_id(options, sha1);
|
return diff_flush_patch_id(options, sha1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_patch_ids(struct rev_info *rev, struct diff_options *options)
|
static void get_patch_ids(struct rev_info *rev, struct diff_options *options, const char *prefix)
|
||||||
{
|
{
|
||||||
struct rev_info check_rev;
|
struct rev_info check_rev;
|
||||||
struct commit *commit;
|
struct commit *commit;
|
||||||
@ -201,7 +203,7 @@ static void get_patch_ids(struct rev_info *rev, struct diff_options *options)
|
|||||||
die("diff_setup_done failed");
|
die("diff_setup_done failed");
|
||||||
|
|
||||||
/* given a range a..b get all patch ids for b..a */
|
/* given a range a..b get all patch ids for b..a */
|
||||||
init_revisions(&check_rev);
|
init_revisions(&check_rev, prefix);
|
||||||
o1->flags ^= UNINTERESTING;
|
o1->flags ^= UNINTERESTING;
|
||||||
o2->flags ^= UNINTERESTING;
|
o2->flags ^= UNINTERESTING;
|
||||||
add_pending_object(&check_rev, o1, "o1");
|
add_pending_object(&check_rev, o1, "o1");
|
||||||
@ -226,7 +228,19 @@ static void get_patch_ids(struct rev_info *rev, struct diff_options *options)
|
|||||||
o2->flags = flags2;
|
o2->flags = flags2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_format_patch(int argc, const char **argv, char **envp)
|
static void gen_message_id(char *dest, unsigned int length, char *base)
|
||||||
|
{
|
||||||
|
const char *committer = git_committer_info(1);
|
||||||
|
const char *email_start = strrchr(committer, '<');
|
||||||
|
const char *email_end = strrchr(committer, '>');
|
||||||
|
if(!email_start || !email_end || email_start > email_end - 1)
|
||||||
|
die("Could not extract email from committer identity.");
|
||||||
|
snprintf(dest, length, "%s.%lu.git.%.*s", base,
|
||||||
|
(unsigned long) time(NULL),
|
||||||
|
(int)(email_end - email_start - 1), email_start + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
struct commit *commit;
|
struct commit *commit;
|
||||||
struct commit **list = NULL;
|
struct commit **list = NULL;
|
||||||
@ -237,11 +251,15 @@ int cmd_format_patch(int argc, const char **argv, char **envp)
|
|||||||
int start_number = -1;
|
int start_number = -1;
|
||||||
int keep_subject = 0;
|
int keep_subject = 0;
|
||||||
int ignore_if_in_upstream = 0;
|
int ignore_if_in_upstream = 0;
|
||||||
|
int thread = 0;
|
||||||
|
const char *in_reply_to = NULL;
|
||||||
struct diff_options patch_id_opts;
|
struct diff_options patch_id_opts;
|
||||||
char *add_signoff = NULL;
|
char *add_signoff = NULL;
|
||||||
|
char message_id[1024];
|
||||||
|
char ref_message_id[1024];
|
||||||
|
|
||||||
git_config(git_format_config);
|
git_config(git_format_config);
|
||||||
init_revisions(&rev);
|
init_revisions(&rev, prefix);
|
||||||
rev.commit_format = CMIT_FMT_EMAIL;
|
rev.commit_format = CMIT_FMT_EMAIL;
|
||||||
rev.verbose_header = 1;
|
rev.verbose_header = 1;
|
||||||
rev.diff = 1;
|
rev.diff = 1;
|
||||||
@ -304,6 +322,16 @@ int cmd_format_patch(int argc, const char **argv, char **envp)
|
|||||||
rev.mime_boundary = argv[i] + 9;
|
rev.mime_boundary = argv[i] + 9;
|
||||||
else if (!strcmp(argv[i], "--ignore-if-in-upstream"))
|
else if (!strcmp(argv[i], "--ignore-if-in-upstream"))
|
||||||
ignore_if_in_upstream = 1;
|
ignore_if_in_upstream = 1;
|
||||||
|
else if (!strcmp(argv[i], "--thread"))
|
||||||
|
thread = 1;
|
||||||
|
else if (!strncmp(argv[i], "--in-reply-to=", 14))
|
||||||
|
in_reply_to = argv[i] + 14;
|
||||||
|
else if (!strcmp(argv[i], "--in-reply-to")) {
|
||||||
|
i++;
|
||||||
|
if (i == argc)
|
||||||
|
die("Need a Message-Id for --in-reply-to");
|
||||||
|
in_reply_to = argv[i];
|
||||||
|
}
|
||||||
else
|
else
|
||||||
argv[j++] = argv[i];
|
argv[j++] = argv[i];
|
||||||
}
|
}
|
||||||
@ -335,7 +363,7 @@ int cmd_format_patch(int argc, const char **argv, char **envp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ignore_if_in_upstream)
|
if (ignore_if_in_upstream)
|
||||||
get_patch_ids(&rev, &patch_id_opts);
|
get_patch_ids(&rev, &patch_id_opts, prefix);
|
||||||
|
|
||||||
if (!use_stdout)
|
if (!use_stdout)
|
||||||
realstdout = fdopen(dup(1), "w");
|
realstdout = fdopen(dup(1), "w");
|
||||||
@ -361,10 +389,23 @@ int cmd_format_patch(int argc, const char **argv, char **envp)
|
|||||||
if (numbered)
|
if (numbered)
|
||||||
rev.total = total + start_number - 1;
|
rev.total = total + start_number - 1;
|
||||||
rev.add_signoff = add_signoff;
|
rev.add_signoff = add_signoff;
|
||||||
|
rev.ref_message_id = in_reply_to;
|
||||||
while (0 <= --nr) {
|
while (0 <= --nr) {
|
||||||
int shown;
|
int shown;
|
||||||
commit = list[nr];
|
commit = list[nr];
|
||||||
rev.nr = total - nr + (start_number - 1);
|
rev.nr = total - nr + (start_number - 1);
|
||||||
|
/* Make the second and subsequent mails replies to the first */
|
||||||
|
if (thread) {
|
||||||
|
if (nr == (total - 2)) {
|
||||||
|
strncpy(ref_message_id, message_id,
|
||||||
|
sizeof(ref_message_id));
|
||||||
|
ref_message_id[sizeof(ref_message_id)-1]='\0';
|
||||||
|
rev.ref_message_id = ref_message_id;
|
||||||
|
}
|
||||||
|
gen_message_id(message_id, sizeof(message_id),
|
||||||
|
sha1_to_hex(commit->object.sha1));
|
||||||
|
rev.message_id = message_id;
|
||||||
|
}
|
||||||
if (!use_stdout)
|
if (!use_stdout)
|
||||||
reopen_stdout(commit, rev.nr, keep_subject);
|
reopen_stdout(commit, rev.nr, keep_subject);
|
||||||
shown = log_tree_commit(&rev, commit);
|
shown = log_tree_commit(&rev, commit);
|
||||||
|
@ -322,14 +322,13 @@ static const char ls_files_usage[] =
|
|||||||
"[ --exclude-per-directory=<filename> ] [--full-name] [--abbrev] "
|
"[ --exclude-per-directory=<filename> ] [--full-name] [--abbrev] "
|
||||||
"[--] [<file>]*";
|
"[--] [<file>]*";
|
||||||
|
|
||||||
int cmd_ls_files(int argc, const char **argv, char** envp)
|
int cmd_ls_files(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int exc_given = 0;
|
int exc_given = 0;
|
||||||
struct dir_struct dir;
|
struct dir_struct dir;
|
||||||
|
|
||||||
memset(&dir, 0, sizeof(dir));
|
memset(&dir, 0, sizeof(dir));
|
||||||
prefix = setup_git_directory();
|
|
||||||
if (prefix)
|
if (prefix)
|
||||||
prefix_offset = strlen(prefix);
|
prefix_offset = strlen(prefix);
|
||||||
git_config(git_default_config);
|
git_config(git_default_config);
|
||||||
|
@ -18,7 +18,7 @@ static int abbrev = 0;
|
|||||||
static int ls_options = 0;
|
static int ls_options = 0;
|
||||||
static const char **pathspec;
|
static const char **pathspec;
|
||||||
static int chomp_prefix = 0;
|
static int chomp_prefix = 0;
|
||||||
static const char *prefix;
|
static const char *ls_tree_prefix;
|
||||||
|
|
||||||
static const char ls_tree_usage[] =
|
static const char ls_tree_usage[] =
|
||||||
"git-ls-tree [-d] [-r] [-t] [-z] [--name-only] [--name-status] [--full-name] [--abbrev[=<n>]] <tree-ish> [path...]";
|
"git-ls-tree [-d] [-r] [-t] [-z] [--name-only] [--name-status] [--full-name] [--abbrev[=<n>]] <tree-ish> [path...]";
|
||||||
@ -71,7 +71,7 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (chomp_prefix &&
|
if (chomp_prefix &&
|
||||||
(baselen < chomp_prefix || memcmp(prefix, base, chomp_prefix)))
|
(baselen < chomp_prefix || memcmp(ls_tree_prefix, base, chomp_prefix)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!(ls_options & LS_NAME_ONLY))
|
if (!(ls_options & LS_NAME_ONLY))
|
||||||
@ -85,13 +85,13 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen,
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_ls_tree(int argc, const char **argv, char **envp)
|
int cmd_ls_tree(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
struct tree *tree;
|
struct tree *tree;
|
||||||
|
|
||||||
prefix = setup_git_directory();
|
|
||||||
git_config(git_default_config);
|
git_config(git_default_config);
|
||||||
|
ls_tree_prefix = prefix;
|
||||||
if (prefix && *prefix)
|
if (prefix && *prefix)
|
||||||
chomp_prefix = strlen(prefix);
|
chomp_prefix = strlen(prefix);
|
||||||
while (1 < argc && argv[1][0] == '-') {
|
while (1 < argc && argv[1][0] == '-') {
|
||||||
|
@ -446,7 +446,7 @@ static int read_one_header_line(char *line, int sz, FILE *in)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Count mbox From headers as headers */
|
/* Count mbox From headers as headers */
|
||||||
if (!ofs && !memcmp(line, "From ", 5))
|
if (!ofs && (!memcmp(line, "From ", 5) || !memcmp(line, ">From ", 6)))
|
||||||
ofs = 1;
|
ofs = 1;
|
||||||
return ofs;
|
return ofs;
|
||||||
}
|
}
|
||||||
@ -836,7 +836,7 @@ int mailinfo(FILE *in, FILE *out, int ks, const char *encoding,
|
|||||||
static const char mailinfo_usage[] =
|
static const char mailinfo_usage[] =
|
||||||
"git-mailinfo [-k] [-u | --encoding=<encoding>] msg patch <mail >info";
|
"git-mailinfo [-k] [-u | --encoding=<encoding>] msg patch <mail >info";
|
||||||
|
|
||||||
int cmd_mailinfo(int argc, const char **argv, char **envp)
|
int cmd_mailinfo(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
/* NEEDSWORK: might want to do the optional .git/ directory
|
/* NEEDSWORK: might want to do the optional .git/ directory
|
||||||
* discovery
|
* discovery
|
||||||
|
@ -138,7 +138,7 @@ out:
|
|||||||
free(name);
|
free(name);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
int cmd_mailsplit(int argc, const char **argv, char **envp)
|
int cmd_mailsplit(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int nr = 0, nr_prec = 4, ret;
|
int nr = 0, nr_prec = 4, ret;
|
||||||
int allow_bare = 0;
|
int allow_bare = 0;
|
||||||
|
297
builtin-mv.c
Normal file
297
builtin-mv.c
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
/*
|
||||||
|
* "git mv" builtin command
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Johannes Schindelin
|
||||||
|
*/
|
||||||
|
#include <fnmatch.h>
|
||||||
|
|
||||||
|
#include "cache.h"
|
||||||
|
#include "builtin.h"
|
||||||
|
#include "dir.h"
|
||||||
|
#include "cache-tree.h"
|
||||||
|
#include "path-list.h"
|
||||||
|
|
||||||
|
static const char builtin_mv_usage[] =
|
||||||
|
"git-mv [-n] [-f] (<source> <destination> | [-k] <source>... <destination>)";
|
||||||
|
|
||||||
|
static const char **copy_pathspec(const char *prefix, const char **pathspec,
|
||||||
|
int count, int base_name)
|
||||||
|
{
|
||||||
|
const char **result = xmalloc((count + 1) * sizeof(const char *));
|
||||||
|
memcpy(result, pathspec, count * sizeof(const char *));
|
||||||
|
result[count] = NULL;
|
||||||
|
if (base_name) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
const char *last_slash = strrchr(result[i], '/');
|
||||||
|
if (last_slash)
|
||||||
|
result[i] = last_slash + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return get_pathspec(prefix, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void show_list(const char *label, struct path_list *list)
|
||||||
|
{
|
||||||
|
if (list->nr > 0) {
|
||||||
|
int i;
|
||||||
|
printf("%s", label);
|
||||||
|
for (i = 0; i < list->nr; i++)
|
||||||
|
printf("%s%s", i > 0 ? ", " : "", list->items[i].path);
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *add_slash(const char *path)
|
||||||
|
{
|
||||||
|
int len = strlen(path);
|
||||||
|
if (path[len - 1] != '/') {
|
||||||
|
char *with_slash = xmalloc(len + 2);
|
||||||
|
memcpy(with_slash, path, len);
|
||||||
|
strcat(with_slash + len, "/");
|
||||||
|
return with_slash;
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct lock_file lock_file;
|
||||||
|
|
||||||
|
int cmd_mv(int argc, const char **argv, const char *prefix)
|
||||||
|
{
|
||||||
|
int i, newfd, count;
|
||||||
|
int verbose = 0, show_only = 0, force = 0, ignore_errors = 0;
|
||||||
|
const char **source, **destination, **dest_path;
|
||||||
|
enum update_mode { BOTH = 0, WORKING_DIRECTORY, INDEX } *modes;
|
||||||
|
struct stat st;
|
||||||
|
struct path_list overwritten = {NULL, 0, 0, 0};
|
||||||
|
struct path_list src_for_dst = {NULL, 0, 0, 0};
|
||||||
|
struct path_list added = {NULL, 0, 0, 0};
|
||||||
|
struct path_list deleted = {NULL, 0, 0, 0};
|
||||||
|
struct path_list changed = {NULL, 0, 0, 0};
|
||||||
|
|
||||||
|
git_config(git_default_config);
|
||||||
|
|
||||||
|
newfd = hold_lock_file_for_update(&lock_file, get_index_file());
|
||||||
|
if (newfd < 0)
|
||||||
|
die("unable to create new index file");
|
||||||
|
|
||||||
|
if (read_cache() < 0)
|
||||||
|
die("index file corrupt");
|
||||||
|
|
||||||
|
for (i = 1; i < argc; i++) {
|
||||||
|
const char *arg = argv[i];
|
||||||
|
|
||||||
|
if (arg[0] != '-')
|
||||||
|
break;
|
||||||
|
if (!strcmp(arg, "--")) {
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!strcmp(arg, "-n")) {
|
||||||
|
show_only = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strcmp(arg, "-f")) {
|
||||||
|
force = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strcmp(arg, "-k")) {
|
||||||
|
ignore_errors = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
die(builtin_mv_usage);
|
||||||
|
}
|
||||||
|
count = argc - i - 1;
|
||||||
|
if (count < 1)
|
||||||
|
usage(builtin_mv_usage);
|
||||||
|
|
||||||
|
source = copy_pathspec(prefix, argv + i, count, 0);
|
||||||
|
modes = xcalloc(count, sizeof(enum update_mode));
|
||||||
|
dest_path = copy_pathspec(prefix, argv + argc - 1, 1, 0);
|
||||||
|
|
||||||
|
if (!lstat(dest_path[0], &st) &&
|
||||||
|
S_ISDIR(st.st_mode)) {
|
||||||
|
dest_path[0] = add_slash(dest_path[0]);
|
||||||
|
destination = copy_pathspec(dest_path[0], argv + i, count, 1);
|
||||||
|
} else {
|
||||||
|
if (count != 1)
|
||||||
|
usage(builtin_mv_usage);
|
||||||
|
destination = dest_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Checking */
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
const char *bad = NULL;
|
||||||
|
|
||||||
|
if (show_only)
|
||||||
|
printf("Checking rename of '%s' to '%s'\n",
|
||||||
|
source[i], destination[i]);
|
||||||
|
|
||||||
|
if (lstat(source[i], &st) < 0)
|
||||||
|
bad = "bad source";
|
||||||
|
|
||||||
|
if (S_ISDIR(st.st_mode)) {
|
||||||
|
const char *dir = source[i], *dest_dir = destination[i];
|
||||||
|
int first, last, len = strlen(dir);
|
||||||
|
|
||||||
|
if (lstat(dest_dir, &st) == 0) {
|
||||||
|
bad = "cannot move directory over file";
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
|
||||||
|
modes[i] = WORKING_DIRECTORY;
|
||||||
|
|
||||||
|
first = cache_name_pos(source[i], len);
|
||||||
|
if (first >= 0)
|
||||||
|
die ("Huh? %s/ is in index?", dir);
|
||||||
|
|
||||||
|
first = -1 - first;
|
||||||
|
for (last = first; last < active_nr; last++) {
|
||||||
|
const char *path = active_cache[last]->name;
|
||||||
|
if (strncmp(path, dir, len) || path[len] != '/')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last - first < 1)
|
||||||
|
bad = "source directory is empty";
|
||||||
|
else if (!bad) {
|
||||||
|
int j, dst_len = strlen(dest_dir);
|
||||||
|
|
||||||
|
if (last - first > 0) {
|
||||||
|
source = realloc(source,
|
||||||
|
(count + last - first)
|
||||||
|
* sizeof(char *));
|
||||||
|
destination = realloc(destination,
|
||||||
|
(count + last - first)
|
||||||
|
* sizeof(char *));
|
||||||
|
modes = realloc(modes,
|
||||||
|
(count + last - first)
|
||||||
|
* sizeof(enum update_mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
dest_dir = add_slash(dest_dir);
|
||||||
|
|
||||||
|
for (j = 0; j < last - first; j++) {
|
||||||
|
const char *path =
|
||||||
|
active_cache[first + j]->name;
|
||||||
|
source[count + j] = path;
|
||||||
|
destination[count + j] =
|
||||||
|
prefix_path(dest_dir, dst_len,
|
||||||
|
path + len);
|
||||||
|
modes[count + j] = INDEX;
|
||||||
|
}
|
||||||
|
count += last - first;
|
||||||
|
}
|
||||||
|
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bad && lstat(destination[i], &st) == 0) {
|
||||||
|
bad = "destination exists";
|
||||||
|
if (force) {
|
||||||
|
/*
|
||||||
|
* only files can overwrite each other:
|
||||||
|
* check both source and destination
|
||||||
|
*/
|
||||||
|
if (S_ISREG(st.st_mode)) {
|
||||||
|
fprintf(stderr, "Warning: %s;"
|
||||||
|
" will overwrite!\n",
|
||||||
|
bad);
|
||||||
|
bad = NULL;
|
||||||
|
path_list_insert(destination[i],
|
||||||
|
&overwritten);
|
||||||
|
} else
|
||||||
|
bad = "Cannot overwrite";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bad &&
|
||||||
|
!strncmp(destination[i], source[i], strlen(source[i])))
|
||||||
|
bad = "can not move directory into itself";
|
||||||
|
|
||||||
|
if (!bad && cache_name_pos(source[i], strlen(source[i])) < 0)
|
||||||
|
bad = "not under version control";
|
||||||
|
|
||||||
|
if (!bad) {
|
||||||
|
if (path_list_has_path(&src_for_dst, destination[i]))
|
||||||
|
bad = "multiple sources for the same target";
|
||||||
|
else
|
||||||
|
path_list_insert(destination[i], &src_for_dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
next:
|
||||||
|
if (bad) {
|
||||||
|
if (ignore_errors) {
|
||||||
|
if (--count > 0) {
|
||||||
|
memmove(source + i, source + i + 1,
|
||||||
|
(count - i) * sizeof(char *));
|
||||||
|
memmove(destination + i,
|
||||||
|
destination + i + 1,
|
||||||
|
(count - i) * sizeof(char *));
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
die ("%s, source=%s, destination=%s",
|
||||||
|
bad, source[i], destination[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (show_only || verbose)
|
||||||
|
printf("Renaming %s to %s\n",
|
||||||
|
source[i], destination[i]);
|
||||||
|
if (!show_only && modes[i] != INDEX &&
|
||||||
|
rename(source[i], destination[i]) < 0 &&
|
||||||
|
!ignore_errors)
|
||||||
|
die ("renaming %s failed: %s",
|
||||||
|
source[i], strerror(errno));
|
||||||
|
|
||||||
|
if (modes[i] == WORKING_DIRECTORY)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (cache_name_pos(source[i], strlen(source[i])) >= 0) {
|
||||||
|
path_list_insert(source[i], &deleted);
|
||||||
|
|
||||||
|
/* destination can be a directory with 1 file inside */
|
||||||
|
if (path_list_has_path(&overwritten, destination[i]))
|
||||||
|
path_list_insert(destination[i], &changed);
|
||||||
|
else
|
||||||
|
path_list_insert(destination[i], &added);
|
||||||
|
} else
|
||||||
|
path_list_insert(destination[i], &added);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (show_only) {
|
||||||
|
show_list("Changed : ", &changed);
|
||||||
|
show_list("Adding : ", &added);
|
||||||
|
show_list("Deleting : ", &deleted);
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < changed.nr; i++) {
|
||||||
|
const char *path = changed.items[i].path;
|
||||||
|
int i = cache_name_pos(path, strlen(path));
|
||||||
|
struct cache_entry *ce = active_cache[i];
|
||||||
|
|
||||||
|
if (i < 0)
|
||||||
|
die ("Huh? Cache entry for %s unknown?", path);
|
||||||
|
refresh_cache_entry(ce, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < added.nr; i++) {
|
||||||
|
const char *path = added.items[i].path;
|
||||||
|
add_file_to_index(path, verbose);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < deleted.nr; i++) {
|
||||||
|
const char *path = deleted.items[i].path;
|
||||||
|
remove_file_from_cache(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (active_cache_changed) {
|
||||||
|
if (write_cache(newfd, active_cache, active_nr) ||
|
||||||
|
close(newfd) ||
|
||||||
|
commit_lock_file(&lock_file))
|
||||||
|
die("Unable to write new index file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -217,7 +217,7 @@ static void add_cache_refs(void)
|
|||||||
add_cache_tree(active_cache_tree);
|
add_cache_tree(active_cache_tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_prune(int argc, const char **argv, char **envp)
|
int cmd_prune(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -234,7 +234,7 @@ int cmd_prune(int argc, const char **argv, char **envp)
|
|||||||
* Set up revision parsing, and mark us as being interested
|
* Set up revision parsing, and mark us as being interested
|
||||||
* in all object types, not just commits.
|
* in all object types, not just commits.
|
||||||
*/
|
*/
|
||||||
init_revisions(&revs);
|
init_revisions(&revs, prefix);
|
||||||
revs.tag_objects = 1;
|
revs.tag_objects = 1;
|
||||||
revs.blob_objects = 1;
|
revs.blob_objects = 1;
|
||||||
revs.tree_objects = 1;
|
revs.tree_objects = 1;
|
||||||
|
@ -270,7 +270,7 @@ static int do_push(const char *repo)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_push(int argc, const char **argv, char **envp)
|
int cmd_push(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
const char *repo = "origin"; /* default repository */
|
const char *repo = "origin"; /* default repository */
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -306,12 +306,12 @@ static void mark_edges_uninteresting(struct commit_list *list)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_rev_list(int argc, const char **argv, char **envp)
|
int cmd_rev_list(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
struct commit_list *list;
|
struct commit_list *list;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
init_revisions(&revs);
|
init_revisions(&revs, prefix);
|
||||||
revs.abbrev = 0;
|
revs.abbrev = 0;
|
||||||
revs.commit_format = CMIT_FMT_UNSPECIFIED;
|
revs.commit_format = CMIT_FMT_UNSPECIFIED;
|
||||||
argc = setup_revisions(argc, argv, &revs, NULL);
|
argc = setup_revisions(argc, argv, &revs, NULL);
|
||||||
|
@ -209,11 +209,10 @@ static int try_difference(const char *arg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_rev_parse(int argc, const char **argv, char **envp)
|
int cmd_rev_parse(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int i, as_is = 0, verify = 0;
|
int i, as_is = 0, verify = 0;
|
||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
const char *prefix = setup_git_directory();
|
|
||||||
|
|
||||||
git_config(git_default_config);
|
git_config(git_default_config);
|
||||||
|
|
||||||
|
@ -43,11 +43,10 @@ static int remove_file(const char *name)
|
|||||||
|
|
||||||
static struct lock_file lock_file;
|
static struct lock_file lock_file;
|
||||||
|
|
||||||
int cmd_rm(int argc, const char **argv, char **envp)
|
int cmd_rm(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int i, newfd;
|
int i, newfd;
|
||||||
int verbose = 0, show_only = 0, force = 0;
|
int verbose = 0, show_only = 0, force = 0;
|
||||||
const char *prefix = setup_git_directory();
|
|
||||||
const char **pathspec;
|
const char **pathspec;
|
||||||
char *seen;
|
char *seen;
|
||||||
|
|
||||||
@ -90,8 +89,7 @@ int cmd_rm(int argc, const char **argv, char **envp)
|
|||||||
seen = NULL;
|
seen = NULL;
|
||||||
for (i = 0; pathspec[i] ; i++)
|
for (i = 0; pathspec[i] ; i++)
|
||||||
/* nothing */;
|
/* nothing */;
|
||||||
seen = xmalloc(i);
|
seen = xcalloc(i, 1);
|
||||||
memset(seen, 0, i);
|
|
||||||
|
|
||||||
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];
|
||||||
|
@ -89,6 +89,8 @@ static int name_first_parent_chain(struct commit *c)
|
|||||||
name_parent(c, p);
|
name_parent(c, p);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
c = p;
|
c = p;
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
@ -172,7 +174,7 @@ static void name_commits(struct commit_list *list,
|
|||||||
static int mark_seen(struct commit *commit, struct commit_list **seen_p)
|
static int mark_seen(struct commit *commit, struct commit_list **seen_p)
|
||||||
{
|
{
|
||||||
if (!commit->object.flags) {
|
if (!commit->object.flags) {
|
||||||
insert_by_date(commit, seen_p);
|
commit_list_insert(commit, seen_p);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -218,9 +220,8 @@ static void join_revs(struct commit_list **list_p,
|
|||||||
* Postprocess to complete well-poisoning.
|
* Postprocess to complete well-poisoning.
|
||||||
*
|
*
|
||||||
* At this point we have all the commits we have seen in
|
* At this point we have all the commits we have seen in
|
||||||
* seen_p list (which happens to be sorted chronologically but
|
* seen_p list. Mark anything that can be reached from
|
||||||
* it does not really matter). Mark anything that can be
|
* uninteresting commits not interesting.
|
||||||
* reached from uninteresting commits not interesting.
|
|
||||||
*/
|
*/
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int changed = 0;
|
int changed = 0;
|
||||||
@ -549,7 +550,7 @@ static int omit_in_dense(struct commit *commit, struct commit **rev, int n)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_show_branch(int ac, const char **av, char **envp)
|
int cmd_show_branch(int ac, const char **av, const char *prefix)
|
||||||
{
|
{
|
||||||
struct commit *rev[MAX_REVS], *commit;
|
struct commit *rev[MAX_REVS], *commit;
|
||||||
struct commit_list *list = NULL, *seen = NULL;
|
struct commit_list *list = NULL, *seen = NULL;
|
||||||
@ -572,7 +573,6 @@ int cmd_show_branch(int ac, const char **av, char **envp)
|
|||||||
int topics = 0;
|
int topics = 0;
|
||||||
int dense = 1;
|
int dense = 1;
|
||||||
|
|
||||||
setup_git_directory();
|
|
||||||
git_config(git_show_branch_config);
|
git_config(git_show_branch_config);
|
||||||
|
|
||||||
/* If nothing is specified, try the default first */
|
/* If nothing is specified, try the default first */
|
||||||
@ -701,6 +701,8 @@ int cmd_show_branch(int ac, const char **av, char **envp)
|
|||||||
if (0 <= extra)
|
if (0 <= extra)
|
||||||
join_revs(&list, &seen, num_rev, extra);
|
join_revs(&list, &seen, num_rev, extra);
|
||||||
|
|
||||||
|
sort_by_date(&seen);
|
||||||
|
|
||||||
if (merge_base)
|
if (merge_base)
|
||||||
return show_merge_base(seen, num_rev);
|
return show_merge_base(seen, num_rev);
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ void stripspace(FILE *in, FILE *out)
|
|||||||
fputc('\n', out);
|
fputc('\n', out);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_stripspace(int argc, const char **argv, char **envp)
|
int cmd_stripspace(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
stripspace(stdin, stdout);
|
stripspace(stdin, stdout);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -20,6 +20,7 @@ static char block[BLOCKSIZE];
|
|||||||
static unsigned long offset;
|
static unsigned long offset;
|
||||||
|
|
||||||
static time_t archive_time;
|
static time_t archive_time;
|
||||||
|
static int tar_umask;
|
||||||
|
|
||||||
/* tries hard to write, either succeeds or dies in the attempt */
|
/* tries hard to write, either succeeds or dies in the attempt */
|
||||||
static void reliable_write(const void *data, unsigned long size)
|
static void reliable_write(const void *data, unsigned long size)
|
||||||
@ -188,13 +189,13 @@ static void write_entry(const unsigned char *sha1, struct strbuf *path,
|
|||||||
} else {
|
} else {
|
||||||
if (S_ISDIR(mode)) {
|
if (S_ISDIR(mode)) {
|
||||||
*header.typeflag = TYPEFLAG_DIR;
|
*header.typeflag = TYPEFLAG_DIR;
|
||||||
mode |= 0777;
|
mode = (mode | 0777) & ~tar_umask;
|
||||||
} else if (S_ISLNK(mode)) {
|
} else if (S_ISLNK(mode)) {
|
||||||
*header.typeflag = TYPEFLAG_LNK;
|
*header.typeflag = TYPEFLAG_LNK;
|
||||||
mode |= 0777;
|
mode |= 0777;
|
||||||
} else if (S_ISREG(mode)) {
|
} else if (S_ISREG(mode)) {
|
||||||
*header.typeflag = TYPEFLAG_REG;
|
*header.typeflag = TYPEFLAG_REG;
|
||||||
mode |= (mode & 0100) ? 0777 : 0666;
|
mode = (mode | ((mode & 0100) ? 0777 : 0666)) & ~tar_umask;
|
||||||
} else {
|
} else {
|
||||||
error("unsupported file mode: 0%o (SHA1: %s)",
|
error("unsupported file mode: 0%o (SHA1: %s)",
|
||||||
mode, sha1_to_hex(sha1));
|
mode, sha1_to_hex(sha1));
|
||||||
@ -293,7 +294,21 @@ static void traverse_tree(struct tree_desc *tree, struct strbuf *path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int generate_tar(int argc, const char **argv, char** envp)
|
int git_tar_config(const char *var, const char *value)
|
||||||
|
{
|
||||||
|
if (!strcmp(var, "tar.umask")) {
|
||||||
|
if (!strcmp(value, "user")) {
|
||||||
|
tar_umask = umask(0);
|
||||||
|
umask(tar_umask);
|
||||||
|
} else {
|
||||||
|
tar_umask = git_config_int(var, value);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return git_default_config(var, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int generate_tar(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
unsigned char sha1[20], tree_sha1[20];
|
unsigned char sha1[20], tree_sha1[20];
|
||||||
struct commit *commit;
|
struct commit *commit;
|
||||||
@ -304,8 +319,7 @@ static int generate_tar(int argc, const char **argv, char** envp)
|
|||||||
current_path.alloc = PATH_MAX;
|
current_path.alloc = PATH_MAX;
|
||||||
current_path.len = current_path.eof = 0;
|
current_path.len = current_path.eof = 0;
|
||||||
|
|
||||||
setup_git_directory();
|
git_config(git_tar_config);
|
||||||
git_config(git_default_config);
|
|
||||||
|
|
||||||
switch (argc) {
|
switch (argc) {
|
||||||
case 3:
|
case 3:
|
||||||
@ -387,19 +401,19 @@ static int remote_tar(int argc, const char **argv)
|
|||||||
return !!ret;
|
return !!ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_tar_tree(int argc, const char **argv, char **envp)
|
int cmd_tar_tree(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
usage(tar_tree_usage);
|
usage(tar_tree_usage);
|
||||||
if (!strncmp("--remote=", argv[1], 9))
|
if (!strncmp("--remote=", argv[1], 9))
|
||||||
return remote_tar(argc, argv);
|
return remote_tar(argc, argv);
|
||||||
return generate_tar(argc, argv, envp);
|
return generate_tar(argc, argv, prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ustar header + extended global header content */
|
/* ustar header + extended global header content */
|
||||||
#define HEADERSIZE (2 * RECORDSIZE)
|
#define HEADERSIZE (2 * RECORDSIZE)
|
||||||
|
|
||||||
int cmd_get_tar_commit_id(int argc, const char **argv, char **envp)
|
int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
char buffer[HEADERSIZE];
|
char buffer[HEADERSIZE];
|
||||||
struct ustar_header *header = (struct ustar_header *)buffer;
|
struct ustar_header *header = (struct ustar_header *)buffer;
|
||||||
|
@ -476,12 +476,11 @@ static int do_reupdate(int ac, const char **av,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_update_index(int argc, const char **argv, char **envp)
|
int cmd_update_index(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int i, newfd, entries, has_errors = 0, line_termination = '\n';
|
int i, newfd, entries, has_errors = 0, line_termination = '\n';
|
||||||
int allow_options = 1;
|
int allow_options = 1;
|
||||||
int read_from_stdin = 0;
|
int read_from_stdin = 0;
|
||||||
const char *prefix = setup_git_directory();
|
|
||||||
int prefix_length = prefix ? strlen(prefix) : 0;
|
int prefix_length = prefix ? strlen(prefix) : 0;
|
||||||
char set_executable_bit = 0;
|
char set_executable_bit = 0;
|
||||||
unsigned int refresh_flags = 0;
|
unsigned int refresh_flags = 0;
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
static const char git_update_ref_usage[] =
|
static const char git_update_ref_usage[] =
|
||||||
"git-update-ref <refname> <value> [<oldval>] [-m <reason>]";
|
"git-update-ref <refname> <value> [<oldval>] [-m <reason>]";
|
||||||
|
|
||||||
int cmd_update_ref(int argc, const char **argv, char **envp)
|
int cmd_update_ref(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
const char *refname=NULL, *value=NULL, *oldval=NULL, *msg=NULL;
|
const char *refname=NULL, *value=NULL, *oldval=NULL, *msg=NULL;
|
||||||
struct ref_lock *lock;
|
struct ref_lock *lock;
|
||||||
@ -13,7 +13,6 @@ int cmd_update_ref(int argc, const char **argv, char **envp)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
setup_ident();
|
setup_ident();
|
||||||
setup_git_directory();
|
|
||||||
git_config(git_default_config);
|
git_config(git_default_config);
|
||||||
|
|
||||||
for (i = 1; i < argc; i++) {
|
for (i = 1; i < argc; i++) {
|
||||||
|
@ -15,7 +15,7 @@ static int nak(const char *reason)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_upload_tar(int argc, const char **argv, char **envp)
|
int cmd_upload_tar(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
const char *dir = argv[1];
|
const char *dir = argv[1];
|
||||||
|
@ -60,14 +60,12 @@ int write_tree(unsigned char *sha1, int missing_ok, const char *prefix)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmd_write_tree(int argc, const char **argv, char **envp)
|
int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
|
||||||
{
|
{
|
||||||
int missing_ok = 0, ret;
|
int missing_ok = 0, ret;
|
||||||
const char *prefix = NULL;
|
const char *prefix = NULL;
|
||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
|
|
||||||
setup_git_directory();
|
|
||||||
|
|
||||||
while (1 < argc) {
|
while (1 < argc) {
|
||||||
const char *arg = argv[1];
|
const char *arg = argv[1];
|
||||||
if (!strcmp(arg, "--missing-ok"))
|
if (!strcmp(arg, "--missing-ok"))
|
||||||
|
77
builtin.h
77
builtin.h
@ -15,53 +15,54 @@ void cmd_usage(int show_all, const char *exec_path, const char *fmt, ...)
|
|||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
|
||||||
extern int cmd_help(int argc, const char **argv, char **envp);
|
extern int cmd_help(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_version(int argc, const char **argv, char **envp);
|
extern int cmd_version(int argc, const char **argv, const char *prefix);
|
||||||
|
|
||||||
extern int cmd_whatchanged(int argc, const char **argv, char **envp);
|
extern int cmd_whatchanged(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_show(int argc, const char **argv, char **envp);
|
extern int cmd_show(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_log(int argc, const char **argv, char **envp);
|
extern int cmd_log(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_diff(int argc, const char **argv, char **envp);
|
extern int cmd_diff(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_format_patch(int argc, const char **argv, char **envp);
|
extern int cmd_format_patch(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_count_objects(int argc, const char **argv, char **envp);
|
extern int cmd_count_objects(int argc, const char **argv, const char *prefix);
|
||||||
|
|
||||||
extern int cmd_prune(int argc, const char **argv, char **envp);
|
extern int cmd_prune(int argc, const char **argv, const char *prefix);
|
||||||
|
|
||||||
extern int cmd_push(int argc, const char **argv, char **envp);
|
extern int cmd_push(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_grep(int argc, const char **argv, char **envp);
|
extern int cmd_grep(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_rm(int argc, const char **argv, char **envp);
|
extern int cmd_rm(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_add(int argc, const char **argv, char **envp);
|
extern int cmd_add(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_rev_list(int argc, const char **argv, char **envp);
|
extern int cmd_rev_list(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_check_ref_format(int argc, const char **argv, char **envp);
|
extern int cmd_check_ref_format(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_init_db(int argc, const char **argv, char **envp);
|
extern int cmd_init_db(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_tar_tree(int argc, const char **argv, char **envp);
|
extern int cmd_tar_tree(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_upload_tar(int argc, const char **argv, char **envp);
|
extern int cmd_upload_tar(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_get_tar_commit_id(int argc, const char **argv, char **envp);
|
extern int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_ls_files(int argc, const char **argv, char **envp);
|
extern int cmd_ls_files(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_ls_tree(int argc, const char **argv, char **envp);
|
extern int cmd_ls_tree(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_read_tree(int argc, const char **argv, char **envp);
|
extern int cmd_read_tree(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_commit_tree(int argc, const char **argv, char **envp);
|
extern int cmd_commit_tree(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_apply(int argc, const char **argv, char **envp);
|
extern int cmd_apply(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_show_branch(int argc, const char **argv, char **envp);
|
extern int cmd_show_branch(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_diff_files(int argc, const char **argv, char **envp);
|
extern int cmd_diff_files(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_diff_index(int argc, const char **argv, char **envp);
|
extern int cmd_diff_index(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_diff_stages(int argc, const char **argv, char **envp);
|
extern int cmd_diff_stages(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_diff_tree(int argc, const char **argv, char **envp);
|
extern int cmd_diff_tree(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_cat_file(int argc, const char **argv, char **envp);
|
extern int cmd_cat_file(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_rev_parse(int argc, const char **argv, char **envp);
|
extern int cmd_rev_parse(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_update_index(int argc, const char **argv, char **envp);
|
extern int cmd_update_index(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_update_ref(int argc, const char **argv, char **envp);
|
extern int cmd_update_ref(int argc, const char **argv, const char *prefix);
|
||||||
extern int cmd_fmt_merge_msg(int argc, const char **argv, char **envp);
|
extern int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix);
|
||||||
|
extern int cmd_mv(int argc, const char **argv, const char *prefix);
|
||||||
|
|
||||||
extern int cmd_write_tree(int argc, const char **argv, char **envp);
|
extern int cmd_write_tree(int argc, const char **argv, const char *prefix);
|
||||||
extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix);
|
extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix);
|
||||||
|
|
||||||
extern int cmd_mailsplit(int argc, const char **argv, char **envp);
|
extern int cmd_mailsplit(int argc, const char **argv, const char *prefix);
|
||||||
extern int split_mbox(const char **mbox, const char *dir, int allow_bare, int nr_prec, int skip);
|
extern int split_mbox(const char **mbox, const char *dir, int allow_bare, int nr_prec, int skip);
|
||||||
|
|
||||||
extern int cmd_mailinfo(int argc, const char **argv, char **envp);
|
extern int cmd_mailinfo(int argc, const char **argv, const char *prefix);
|
||||||
extern int mailinfo(FILE *in, FILE *out, int ks, const char *encoding, const char *msg, const char *patch);
|
extern int mailinfo(FILE *in, FILE *out, int ks, const char *encoding, const char *msg, const char *patch);
|
||||||
|
|
||||||
extern int cmd_stripspace(int argc, const char **argv, char **envp);
|
extern int cmd_stripspace(int argc, const char **argv, const char *prefix);
|
||||||
extern void stripspace(FILE *in, FILE *out);
|
extern void stripspace(FILE *in, FILE *out);
|
||||||
#endif
|
#endif
|
||||||
|
2
cache.h
2
cache.h
@ -155,6 +155,7 @@ extern int add_cache_entry(struct cache_entry *ce, int option);
|
|||||||
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 int remove_cache_entry_at(int pos);
|
extern int remove_cache_entry_at(int pos);
|
||||||
extern int remove_file_from_cache(const char *path);
|
extern int remove_file_from_cache(const char *path);
|
||||||
|
extern int add_file_to_index(const char *path, int verbose);
|
||||||
extern int ce_same_name(struct cache_entry *a, struct cache_entry *b);
|
extern int ce_same_name(struct cache_entry *a, struct cache_entry *b);
|
||||||
extern int ce_match_stat(struct cache_entry *ce, struct stat *st, int);
|
extern int ce_match_stat(struct cache_entry *ce, struct stat *st, int);
|
||||||
extern int ce_modified(struct cache_entry *ce, struct stat *st, int);
|
extern int ce_modified(struct cache_entry *ce, struct stat *st, int);
|
||||||
@ -180,6 +181,7 @@ extern int commit_lock_file(struct lock_file *);
|
|||||||
extern void rollback_lock_file(struct lock_file *);
|
extern void rollback_lock_file(struct lock_file *);
|
||||||
|
|
||||||
/* Environment bits from configuration mechanism */
|
/* Environment bits from configuration mechanism */
|
||||||
|
extern int use_legacy_headers;
|
||||||
extern int trust_executable_bit;
|
extern int trust_executable_bit;
|
||||||
extern int assume_unchanged;
|
extern int assume_unchanged;
|
||||||
extern int prefer_symlink_refs;
|
extern int prefer_symlink_refs;
|
||||||
|
@ -639,8 +639,7 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent,
|
|||||||
/* deleted file */
|
/* deleted file */
|
||||||
result_size = 0;
|
result_size = 0;
|
||||||
elem->mode = 0;
|
elem->mode = 0;
|
||||||
result = xmalloc(1);
|
result = xcalloc(1, 1);
|
||||||
result[0] = 0;
|
|
||||||
}
|
}
|
||||||
if (0 <= fd)
|
if (0 <= fd)
|
||||||
close(fd);
|
close(fd);
|
||||||
|
5
config.c
5
config.c
@ -279,6 +279,11 @@ int git_default_config(const char *var, const char *value)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strcmp(var, "core.legacyheaders")) {
|
||||||
|
use_legacy_headers = git_config_bool(var, value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!strcmp(var, "core.compression")) {
|
if (!strcmp(var, "core.compression")) {
|
||||||
int level = git_config_int(var, value);
|
int level = git_config_int(var, value);
|
||||||
if (level == -1)
|
if (level == -1)
|
||||||
|
24
config.mak.in
Normal file
24
config.mak.in
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# git Makefile configuration, included in main Makefile
|
||||||
|
# @configure_input@
|
||||||
|
|
||||||
|
CC = @CC@
|
||||||
|
AR = @AR@
|
||||||
|
TAR = @TAR@
|
||||||
|
#INSTALL = @INSTALL@ # needs install-sh or install.sh in sources
|
||||||
|
|
||||||
|
prefix = @prefix@
|
||||||
|
exec_prefix = @exec_prefix@
|
||||||
|
bindir = @bindir@
|
||||||
|
#gitexecdir = @libexecdir@/git-core/
|
||||||
|
datarootdir = @datarootdir@
|
||||||
|
template_dir = @datadir@/git-core/templates/
|
||||||
|
GIT_PYTHON_DIR = @datadir@/git-core/python
|
||||||
|
|
||||||
|
mandir=@mandir@
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
|
||||||
|
export exec_prefix mandir
|
||||||
|
export srcdir VPATH
|
||||||
|
|
183
configure.ac
Normal file
183
configure.ac
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
# -*- Autoconf -*-
|
||||||
|
# Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
|
AC_PREREQ(2.59)
|
||||||
|
AC_INIT([git], [1.4.1], [git@vger.kernel.org])
|
||||||
|
|
||||||
|
AC_CONFIG_SRCDIR([git.c])
|
||||||
|
|
||||||
|
config_file=config.mak.autogen
|
||||||
|
config_append=config.mak.append
|
||||||
|
config_in=config.mak.in
|
||||||
|
|
||||||
|
echo "# ${config_append}. Generated by configure." > "${config_append}"
|
||||||
|
|
||||||
|
|
||||||
|
## Definitions of macros
|
||||||
|
# GIT_CONF_APPEND_LINE(LINE)
|
||||||
|
# --------------------------
|
||||||
|
# Append LINE to file ${config_append}
|
||||||
|
AC_DEFUN([GIT_CONF_APPEND_LINE],
|
||||||
|
[echo "$1" >> "${config_append}"])# GIT_CONF_APPEND_LINE
|
||||||
|
|
||||||
|
|
||||||
|
## Checks for programs.
|
||||||
|
AC_MSG_NOTICE([CHECKS for programs])
|
||||||
|
#
|
||||||
|
AC_PROG_CC
|
||||||
|
#AC_PROG_INSTALL # needs install-sh or install.sh in sources
|
||||||
|
AC_CHECK_TOOL(AR, ar, :)
|
||||||
|
AC_CHECK_PROGS(TAR, [gtar tar])
|
||||||
|
#
|
||||||
|
# Define NO_PYTHON if you want to lose all benefits of the recursive merge.
|
||||||
|
|
||||||
|
|
||||||
|
## Checks for libraries.
|
||||||
|
AC_MSG_NOTICE([CHECKS for libraries])
|
||||||
|
#
|
||||||
|
# Define NO_OPENSSL environment variable if you do not have OpenSSL.
|
||||||
|
# Define NEEDS_SSL_WITH_CRYPTO if you need -lcrypto with -lssl (Darwin).
|
||||||
|
AC_CHECK_LIB([ssl], [SHA1_Init],[],
|
||||||
|
[AC_CHECK_LIB([crypto], [SHA1_INIT],
|
||||||
|
[GIT_CONF_APPEND_LINE(NEEDS_SSL_WITH_CRYPTO=YesPlease)],
|
||||||
|
[GIT_CONF_APPEND_LINE(NO_OPENSSL=YesPlease)])])
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
AC_CHECK_LIB([curl], [curl_global_init],[],
|
||||||
|
[GIT_CONF_APPEND_LINE(NO_CURL=YesPlease)])
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
AC_CHECK_LIB([expat], [XML_ParserCreate],[],
|
||||||
|
[GIT_CONF_APPEND_LINE(NO_EXPAT=YesPlease)])
|
||||||
|
#
|
||||||
|
# Define NEEDS_LIBICONV if linking with libc is not enough (Darwin).
|
||||||
|
AC_CHECK_LIB([c], [iconv],[],
|
||||||
|
[AC_CHECK_LIB([iconv],[iconv],
|
||||||
|
[GIT_CONF_APPEND_LINE(NEEDS_LIBICONV=YesPlease)],[])])
|
||||||
|
#
|
||||||
|
# Define NEEDS_SOCKET if linking with libc is not enough (SunOS,
|
||||||
|
# Patrick Mauritz).
|
||||||
|
AC_CHECK_LIB([c], [socket],[],
|
||||||
|
[AC_CHECK_LIB([socket],[socket],
|
||||||
|
[GIT_CONF_APPEND_LINE(NEEDS_SOCKET=YesPlease)],[])])
|
||||||
|
|
||||||
|
|
||||||
|
## Checks for header files.
|
||||||
|
|
||||||
|
|
||||||
|
## Checks for typedefs, structures, and compiler characteristics.
|
||||||
|
AC_MSG_NOTICE([CHECKS for typedefs, structures, and compiler characteristics])
|
||||||
|
#
|
||||||
|
# Define NO_D_INO_IN_DIRENT if you don't have d_ino in your struct dirent.
|
||||||
|
AC_CHECK_MEMBER(struct dirent.d_ino,[],
|
||||||
|
[GIT_CONF_APPEND_LINE(NO_D_INO_IN_DIRENT=YesPlease)],
|
||||||
|
[#include <dirent.h>])
|
||||||
|
#
|
||||||
|
# Define NO_D_TYPE_IN_DIRENT if your platform defines DT_UNKNOWN but lacks
|
||||||
|
# d_type in struct dirent (latest Cygwin -- will be fixed soonish).
|
||||||
|
AC_CHECK_MEMBER(struct dirent.d_type,[],
|
||||||
|
[GIT_CONF_APPEND_LINE(NO_D_TYPE_IN_DIRENT=YesPlease)],
|
||||||
|
[#include <dirent.h>])
|
||||||
|
#
|
||||||
|
# Define NO_SOCKADDR_STORAGE if your platform does not have struct
|
||||||
|
# sockaddr_storage.
|
||||||
|
AC_CHECK_TYPE(struct sockaddr_storage,[],
|
||||||
|
[GIT_CONF_APPEND_LINE(NO_SOCKADDR_STORAGE=YesPlease)],
|
||||||
|
[#include <netinet/in.h>])
|
||||||
|
|
||||||
|
|
||||||
|
## Checks for library functions.
|
||||||
|
## (in default C library and libraries checked by AC_CHECK_LIB)
|
||||||
|
AC_MSG_NOTICE([CHECKS for library functions])
|
||||||
|
#
|
||||||
|
# Define NO_STRCASESTR if you don't have strcasestr.
|
||||||
|
AC_CHECK_FUNC(strcasestr,[],
|
||||||
|
[GIT_CONF_APPEND_LINE(NO_STRCASESTR=YesPlease)])
|
||||||
|
#
|
||||||
|
# Define NO_STRLCPY if you don't have strlcpy.
|
||||||
|
AC_CHECK_FUNC(strlcpy,[],
|
||||||
|
[GIT_CONF_APPEND_LINE(NO_STRLCPY=YesPlease)])
|
||||||
|
#
|
||||||
|
# Define NO_SETENV if you don't have setenv in the C library.
|
||||||
|
AC_CHECK_FUNC(setenv,[],
|
||||||
|
[GIT_CONF_APPEND_LINE(NO_SETENV=YesPlease)])
|
||||||
|
#
|
||||||
|
# Define NO_MMAP if you want to avoid mmap.
|
||||||
|
#
|
||||||
|
# Define NO_IPV6 if you lack IPv6 support and getaddrinfo().
|
||||||
|
#
|
||||||
|
# Define NO_ICONV if your libc does not properly support iconv.
|
||||||
|
|
||||||
|
|
||||||
|
## Other checks.
|
||||||
|
# Define USE_PIC if you need the main git objects to be built with -fPIC
|
||||||
|
# in order to build and link perl/Git.so. x86-64 seems to need this.
|
||||||
|
#
|
||||||
|
# Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link.
|
||||||
|
# Enable it on Windows. By default, symrefs are still used.
|
||||||
|
#
|
||||||
|
# Define WITH_OWN_SUBPROCESS_PY if you want to use with python 2.3.
|
||||||
|
#
|
||||||
|
# Define NO_ACCURATE_DIFF if your diff program at least sometimes misses
|
||||||
|
# a missing newline at the end of the file.
|
||||||
|
|
||||||
|
|
||||||
|
## Site configuration
|
||||||
|
## --with-PACKAGE[=ARG] and --without-PACKAGE
|
||||||
|
# Define NO_SVN_TESTS if you want to skip time-consuming SVN interopability
|
||||||
|
# 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 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.
|
||||||
|
#
|
||||||
|
# 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 NO_MMAP if you want to avoid mmap.
|
||||||
|
#
|
||||||
|
# Define NO_PYTHON if you want to loose all benefits of the recursive merge.
|
||||||
|
#
|
||||||
|
## --enable-FEATURE[=ARG] and --disable-FEATURE
|
||||||
|
# Define COLLISION_CHECK below if you believe that SHA1's
|
||||||
|
# 1461501637330902918203684832716283019655932542976 hashes do not give you
|
||||||
|
# sufficient guarantee that no collisions between objects will ever happen.
|
||||||
|
#
|
||||||
|
# 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-cache perspective.
|
||||||
|
|
||||||
|
|
||||||
|
## Output files
|
||||||
|
AC_CONFIG_FILES(["${config_file}":"${config_in}":"${config_append}"])
|
||||||
|
AC_OUTPUT
|
||||||
|
|
||||||
|
|
||||||
|
## Cleanup
|
||||||
|
rm -f "${config_append}"
|
@ -3,9 +3,9 @@
|
|||||||
EMACS = emacs
|
EMACS = emacs
|
||||||
|
|
||||||
ELC = git.elc vc-git.elc
|
ELC = git.elc vc-git.elc
|
||||||
INSTALL = install
|
INSTALL ?= install
|
||||||
INSTALL_ELC = $(INSTALL) -m 644
|
INSTALL_ELC = $(INSTALL) -m 644
|
||||||
prefix = $(HOME)
|
prefix ?= $(HOME)
|
||||||
emacsdir = $(prefix)/share/emacs/site-lisp
|
emacsdir = $(prefix)/share/emacs/site-lisp
|
||||||
|
|
||||||
all: $(ELC)
|
all: $(ELC)
|
||||||
|
@ -55,7 +55,8 @@
|
|||||||
;;;; ------------------------------------------------------------
|
;;;; ------------------------------------------------------------
|
||||||
|
|
||||||
(defgroup git nil
|
(defgroup git nil
|
||||||
"Git user interface")
|
"A user interface for the git versioning system."
|
||||||
|
:group 'tools)
|
||||||
|
|
||||||
(defcustom git-committer-name nil
|
(defcustom git-committer-name nil
|
||||||
"User name to use for commits.
|
"User name to use for commits.
|
||||||
@ -83,6 +84,12 @@ then to `add-log-mailing-address' and then to `user-mail-address'."
|
|||||||
:group 'git
|
:group 'git
|
||||||
:type 'boolean)
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom git-reuse-status-buffer t
|
||||||
|
"Whether `git-status' should try to reuse an existing buffer
|
||||||
|
if there is already one that displays the same directory."
|
||||||
|
:group 'git
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
(defcustom git-per-dir-ignore-file ".gitignore"
|
(defcustom git-per-dir-ignore-file ".gitignore"
|
||||||
"Name of the per-directory ignore file."
|
"Name of the per-directory ignore file."
|
||||||
:group 'git
|
:group 'git
|
||||||
@ -258,7 +265,7 @@ and returns the process output as a string."
|
|||||||
(set-buffer (find-file-noselect ignore-name))
|
(set-buffer (find-file-noselect ignore-name))
|
||||||
(goto-char (point-max))
|
(goto-char (point-max))
|
||||||
(unless (zerop (current-column)) (insert "\n"))
|
(unless (zerop (current-column)) (insert "\n"))
|
||||||
(insert name "\n")
|
(insert "/" name "\n")
|
||||||
(sort-lines nil (point-min) (point-max))
|
(sort-lines nil (point-min) (point-max))
|
||||||
(save-buffer))
|
(save-buffer))
|
||||||
(when created
|
(when created
|
||||||
@ -584,6 +591,8 @@ and returns the process output as a string."
|
|||||||
(condition-case nil (delete-file ".git/MERGE_HEAD") (error nil))
|
(condition-case nil (delete-file ".git/MERGE_HEAD") (error nil))
|
||||||
(with-current-buffer buffer (erase-buffer))
|
(with-current-buffer buffer (erase-buffer))
|
||||||
(git-set-files-state files 'uptodate)
|
(git-set-files-state files 'uptodate)
|
||||||
|
(when (file-directory-p ".git/rr-cache")
|
||||||
|
(git-run-command nil nil "rerere"))
|
||||||
(git-refresh-files)
|
(git-refresh-files)
|
||||||
(git-refresh-ewoc-hf git-status)
|
(git-refresh-ewoc-hf git-status)
|
||||||
(message "Committed %s." commit))
|
(message "Committed %s." commit))
|
||||||
@ -1001,12 +1010,28 @@ Commands:
|
|||||||
(set (make-local-variable 'list-buffers-directory) default-directory)
|
(set (make-local-variable 'list-buffers-directory) default-directory)
|
||||||
(run-hooks 'git-status-mode-hook)))
|
(run-hooks 'git-status-mode-hook)))
|
||||||
|
|
||||||
|
(defun git-find-status-buffer (dir)
|
||||||
|
"Find the git status buffer handling a specified directory."
|
||||||
|
(let ((list (buffer-list))
|
||||||
|
(fulldir (expand-file-name dir))
|
||||||
|
found)
|
||||||
|
(while (and list (not found))
|
||||||
|
(let ((buffer (car list)))
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(when (and list-buffers-directory
|
||||||
|
(string-equal fulldir (expand-file-name list-buffers-directory))
|
||||||
|
(string-match "\\*git-status\\*$" (buffer-name buffer)))
|
||||||
|
(setq found buffer))))
|
||||||
|
(setq list (cdr list)))
|
||||||
|
found))
|
||||||
|
|
||||||
(defun git-status (dir)
|
(defun git-status (dir)
|
||||||
"Entry point into git-status mode."
|
"Entry point into git-status mode."
|
||||||
(interactive "DSelect directory: ")
|
(interactive "DSelect directory: ")
|
||||||
(setq dir (git-get-top-dir dir))
|
(setq dir (git-get-top-dir dir))
|
||||||
(if (file-directory-p (concat (file-name-as-directory dir) ".git"))
|
(if (file-directory-p (concat (file-name-as-directory dir) ".git"))
|
||||||
(let ((buffer (create-file-buffer (expand-file-name "*git-status*" dir))))
|
(let ((buffer (or (and git-reuse-status-buffer (git-find-status-buffer dir))
|
||||||
|
(create-file-buffer (expand-file-name "*git-status*" dir)))))
|
||||||
(switch-to-buffer buffer)
|
(switch-to-buffer buffer)
|
||||||
(cd dir)
|
(cd dir)
|
||||||
(git-status-mode)
|
(git-status-mode)
|
||||||
|
2
daemon.c
2
daemon.c
@ -19,7 +19,7 @@ static const char daemon_usage[] =
|
|||||||
"git-daemon [--verbose] [--syslog] [--inetd | --port=n] [--export-all]\n"
|
"git-daemon [--verbose] [--syslog] [--inetd | --port=n] [--export-all]\n"
|
||||||
" [--timeout=n] [--init-timeout=n] [--strict-paths]\n"
|
" [--timeout=n] [--init-timeout=n] [--strict-paths]\n"
|
||||||
" [--base-path=path] [--user-path | --user-path=path]\n"
|
" [--base-path=path] [--user-path | --user-path=path]\n"
|
||||||
" [--reuseaddr] [directory...]";
|
" [--reuseaddr] [--detach] [--pid-file=file] [directory...]";
|
||||||
|
|
||||||
/* List of acceptable pathname prefixes */
|
/* List of acceptable pathname prefixes */
|
||||||
static char **ok_paths = NULL;
|
static char **ok_paths = NULL;
|
||||||
|
28
diff.c
28
diff.c
@ -17,15 +17,6 @@ static int diff_detect_rename_default = 0;
|
|||||||
static int diff_rename_limit_default = -1;
|
static int diff_rename_limit_default = -1;
|
||||||
static int diff_use_color_default = 0;
|
static int diff_use_color_default = 0;
|
||||||
|
|
||||||
enum color_diff {
|
|
||||||
DIFF_RESET = 0,
|
|
||||||
DIFF_PLAIN = 1,
|
|
||||||
DIFF_METAINFO = 2,
|
|
||||||
DIFF_FRAGINFO = 3,
|
|
||||||
DIFF_FILE_OLD = 4,
|
|
||||||
DIFF_FILE_NEW = 5,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* "\033[1;38;5;2xx;48;5;2xxm\0" is 23 bytes */
|
/* "\033[1;38;5;2xx;48;5;2xxm\0" is 23 bytes */
|
||||||
static char diff_colors[][24] = {
|
static char diff_colors[][24] = {
|
||||||
"\033[m", /* reset */
|
"\033[m", /* reset */
|
||||||
@ -33,7 +24,8 @@ static char diff_colors[][24] = {
|
|||||||
"\033[1m", /* bold */
|
"\033[1m", /* bold */
|
||||||
"\033[36m", /* cyan */
|
"\033[36m", /* cyan */
|
||||||
"\033[31m", /* red */
|
"\033[31m", /* red */
|
||||||
"\033[32m" /* green */
|
"\033[32m", /* green */
|
||||||
|
"\033[33m" /* yellow */
|
||||||
};
|
};
|
||||||
|
|
||||||
static int parse_diff_color_slot(const char *var, int ofs)
|
static int parse_diff_color_slot(const char *var, int ofs)
|
||||||
@ -48,6 +40,8 @@ static int parse_diff_color_slot(const char *var, int ofs)
|
|||||||
return DIFF_FILE_OLD;
|
return DIFF_FILE_OLD;
|
||||||
if (!strcasecmp(var+ofs, "new"))
|
if (!strcasecmp(var+ofs, "new"))
|
||||||
return DIFF_FILE_NEW;
|
return DIFF_FILE_NEW;
|
||||||
|
if (!strcasecmp(var+ofs, "commit"))
|
||||||
|
return DIFF_COMMIT;
|
||||||
die("bad config variable '%s'", var);
|
die("bad config variable '%s'", var);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,7 +364,7 @@ struct emit_callback {
|
|||||||
const char **label_path;
|
const char **label_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline const char *get_color(int diff_use_color, enum color_diff ix)
|
const char *diff_get_color(int diff_use_color, enum color_diff ix)
|
||||||
{
|
{
|
||||||
if (diff_use_color)
|
if (diff_use_color)
|
||||||
return diff_colors[ix];
|
return diff_colors[ix];
|
||||||
@ -381,8 +375,8 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct emit_callback *ecbdata = priv;
|
struct emit_callback *ecbdata = priv;
|
||||||
const char *set = get_color(ecbdata->color_diff, DIFF_METAINFO);
|
const char *set = diff_get_color(ecbdata->color_diff, DIFF_METAINFO);
|
||||||
const char *reset = get_color(ecbdata->color_diff, DIFF_RESET);
|
const char *reset = diff_get_color(ecbdata->color_diff, DIFF_RESET);
|
||||||
|
|
||||||
if (ecbdata->label_path[0]) {
|
if (ecbdata->label_path[0]) {
|
||||||
printf("%s--- %s%s\n", set, ecbdata->label_path[0], reset);
|
printf("%s--- %s%s\n", set, ecbdata->label_path[0], reset);
|
||||||
@ -397,7 +391,7 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
|
|||||||
;
|
;
|
||||||
if (2 <= i && i < len && line[i] == ' ') {
|
if (2 <= i && i < len && line[i] == ' ') {
|
||||||
ecbdata->nparents = i - 1;
|
ecbdata->nparents = i - 1;
|
||||||
set = get_color(ecbdata->color_diff, DIFF_FRAGINFO);
|
set = diff_get_color(ecbdata->color_diff, DIFF_FRAGINFO);
|
||||||
}
|
}
|
||||||
else if (len < ecbdata->nparents)
|
else if (len < ecbdata->nparents)
|
||||||
set = reset;
|
set = reset;
|
||||||
@ -410,7 +404,7 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
|
|||||||
else if (line[i] == '+')
|
else if (line[i] == '+')
|
||||||
color = DIFF_FILE_NEW;
|
color = DIFF_FILE_NEW;
|
||||||
}
|
}
|
||||||
set = get_color(ecbdata->color_diff, color);
|
set = diff_get_color(ecbdata->color_diff, color);
|
||||||
}
|
}
|
||||||
if (len > 0 && line[len-1] == '\n')
|
if (len > 0 && line[len-1] == '\n')
|
||||||
len--;
|
len--;
|
||||||
@ -767,8 +761,8 @@ static void builtin_diff(const char *name_a,
|
|||||||
mmfile_t mf1, mf2;
|
mmfile_t mf1, mf2;
|
||||||
const char *lbl[2];
|
const char *lbl[2];
|
||||||
char *a_one, *b_two;
|
char *a_one, *b_two;
|
||||||
const char *set = get_color(o->color_diff, DIFF_METAINFO);
|
const char *set = diff_get_color(o->color_diff, DIFF_METAINFO);
|
||||||
const char *reset = get_color(o->color_diff, DIFF_RESET);
|
const char *reset = diff_get_color(o->color_diff, DIFF_RESET);
|
||||||
|
|
||||||
a_one = quote_two("a/", name_a);
|
a_one = quote_two("a/", name_a);
|
||||||
b_two = quote_two("b/", name_b);
|
b_two = quote_two("b/", name_b);
|
||||||
|
11
diff.h
11
diff.h
@ -69,6 +69,17 @@ struct diff_options {
|
|||||||
add_remove_fn_t add_remove;
|
add_remove_fn_t add_remove;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum color_diff {
|
||||||
|
DIFF_RESET = 0,
|
||||||
|
DIFF_PLAIN = 1,
|
||||||
|
DIFF_METAINFO = 2,
|
||||||
|
DIFF_FRAGINFO = 3,
|
||||||
|
DIFF_FILE_OLD = 4,
|
||||||
|
DIFF_FILE_NEW = 5,
|
||||||
|
DIFF_COMMIT = 6,
|
||||||
|
};
|
||||||
|
const char *diff_get_color(int diff_use_color, enum color_diff ix);
|
||||||
|
|
||||||
extern const char mime_boundary_leader[];
|
extern const char mime_boundary_leader[];
|
||||||
|
|
||||||
extern void diff_tree_setup_paths(const char **paths, struct diff_options *);
|
extern void diff_tree_setup_paths(const char **paths, struct diff_options *);
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
char git_default_email[MAX_GITNAME];
|
char git_default_email[MAX_GITNAME];
|
||||||
char git_default_name[MAX_GITNAME];
|
char git_default_name[MAX_GITNAME];
|
||||||
|
int use_legacy_headers = 1;
|
||||||
int trust_executable_bit = 1;
|
int trust_executable_bit = 1;
|
||||||
int assume_unchanged = 0;
|
int assume_unchanged = 0;
|
||||||
int prefer_symlink_refs = 0;
|
int prefer_symlink_refs = 0;
|
||||||
|
112
fetch.c
112
fetch.c
@ -7,9 +7,7 @@
|
|||||||
#include "tag.h"
|
#include "tag.h"
|
||||||
#include "blob.h"
|
#include "blob.h"
|
||||||
#include "refs.h"
|
#include "refs.h"
|
||||||
|
#include "strbuf.h"
|
||||||
const char *write_ref = NULL;
|
|
||||||
const char *write_ref_log_details = NULL;
|
|
||||||
|
|
||||||
int get_tree = 0;
|
int get_tree = 0;
|
||||||
int get_history = 0;
|
int get_history = 0;
|
||||||
@ -213,54 +211,106 @@ static int mark_complete(const char *path, const unsigned char *sha1)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pull(char *target)
|
int pull_targets_stdin(char ***target, const char ***write_ref)
|
||||||
{
|
{
|
||||||
struct ref_lock *lock = NULL;
|
int targets = 0, targets_alloc = 0;
|
||||||
unsigned char sha1[20];
|
struct strbuf buf;
|
||||||
|
*target = NULL; *write_ref = NULL;
|
||||||
|
strbuf_init(&buf);
|
||||||
|
while (1) {
|
||||||
|
char *rf_one = NULL;
|
||||||
|
char *tg_one;
|
||||||
|
|
||||||
|
read_line(&buf, stdin, '\n');
|
||||||
|
if (buf.eof)
|
||||||
|
break;
|
||||||
|
tg_one = buf.buf;
|
||||||
|
rf_one = strchr(tg_one, '\t');
|
||||||
|
if (rf_one)
|
||||||
|
*rf_one++ = 0;
|
||||||
|
|
||||||
|
if (targets >= targets_alloc) {
|
||||||
|
targets_alloc = targets_alloc ? targets_alloc * 2 : 64;
|
||||||
|
*target = xrealloc(*target, targets_alloc * sizeof(**target));
|
||||||
|
*write_ref = xrealloc(*write_ref, targets_alloc * sizeof(**write_ref));
|
||||||
|
}
|
||||||
|
(*target)[targets] = strdup(tg_one);
|
||||||
|
(*write_ref)[targets] = rf_one ? strdup(rf_one) : NULL;
|
||||||
|
targets++;
|
||||||
|
}
|
||||||
|
return targets;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pull_targets_free(int targets, char **target, const char **write_ref)
|
||||||
|
{
|
||||||
|
while (targets--) {
|
||||||
|
free(target[targets]);
|
||||||
|
if (write_ref && write_ref[targets])
|
||||||
|
free((char *) write_ref[targets]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int pull(int targets, char **target, const char **write_ref,
|
||||||
|
const char *write_ref_log_details)
|
||||||
|
{
|
||||||
|
struct ref_lock **lock = xcalloc(targets, sizeof(struct ref_lock *));
|
||||||
|
unsigned char *sha1 = xmalloc(targets * 20);
|
||||||
char *msg;
|
char *msg;
|
||||||
int ret;
|
int ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
save_commit_buffer = 0;
|
save_commit_buffer = 0;
|
||||||
track_object_refs = 0;
|
track_object_refs = 0;
|
||||||
if (write_ref) {
|
|
||||||
lock = lock_ref_sha1(write_ref, NULL, 0);
|
for (i = 0; i < targets; i++) {
|
||||||
if (!lock) {
|
if (!write_ref || !write_ref[i])
|
||||||
error("Can't lock ref %s", write_ref);
|
continue;
|
||||||
return -1;
|
|
||||||
|
lock[i] = lock_ref_sha1(write_ref[i], NULL, 0);
|
||||||
|
if (!lock[i]) {
|
||||||
|
error("Can't lock ref %s", write_ref[i]);
|
||||||
|
goto unlock_and_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!get_recover)
|
if (!get_recover)
|
||||||
for_each_ref(mark_complete);
|
for_each_ref(mark_complete);
|
||||||
|
|
||||||
if (interpret_target(target, sha1)) {
|
for (i = 0; i < targets; i++) {
|
||||||
error("Could not interpret %s as something to pull", target);
|
if (interpret_target(target[i], &sha1[20 * i])) {
|
||||||
if (lock)
|
error("Could not interpret %s as something to pull", target[i]);
|
||||||
unlock_ref(lock);
|
goto unlock_and_fail;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
if (process(lookup_unknown_object(sha1))) {
|
if (process(lookup_unknown_object(&sha1[20 * i])))
|
||||||
if (lock)
|
goto unlock_and_fail;
|
||||||
unlock_ref(lock);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (loop()) {
|
|
||||||
if (lock)
|
|
||||||
unlock_ref(lock);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (write_ref) {
|
if (loop())
|
||||||
|
goto unlock_and_fail;
|
||||||
|
|
||||||
if (write_ref_log_details) {
|
if (write_ref_log_details) {
|
||||||
msg = xmalloc(strlen(write_ref_log_details) + 12);
|
msg = xmalloc(strlen(write_ref_log_details) + 12);
|
||||||
sprintf(msg, "fetch from %s", write_ref_log_details);
|
sprintf(msg, "fetch from %s", write_ref_log_details);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
msg = NULL;
|
msg = NULL;
|
||||||
ret = write_ref_sha1(lock, sha1, msg ? msg : "fetch (unknown)");
|
}
|
||||||
|
for (i = 0; i < targets; i++) {
|
||||||
|
if (!write_ref || !write_ref[i])
|
||||||
|
continue;
|
||||||
|
ret = write_ref_sha1(lock[i], &sha1[20 * i], msg ? msg : "fetch (unknown)");
|
||||||
|
lock[i] = NULL;
|
||||||
|
if (ret)
|
||||||
|
goto unlock_and_fail;
|
||||||
|
}
|
||||||
if (msg)
|
if (msg)
|
||||||
free(msg);
|
free(msg);
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
unlock_and_fail:
|
||||||
|
for (i = 0; i < targets; i++)
|
||||||
|
if (lock[i])
|
||||||
|
unlock_ref(lock[i]);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
17
fetch.h
17
fetch.h
@ -22,12 +22,6 @@ extern void prefetch(unsigned char *sha1);
|
|||||||
*/
|
*/
|
||||||
extern int fetch_ref(char *ref, unsigned char *sha1);
|
extern int fetch_ref(char *ref, unsigned char *sha1);
|
||||||
|
|
||||||
/* If set, the ref filename to write the target value to. */
|
|
||||||
extern const char *write_ref;
|
|
||||||
|
|
||||||
/* If set additional text will appear in the ref log. */
|
|
||||||
extern const char *write_ref_log_details;
|
|
||||||
|
|
||||||
/* Set to fetch the target tree. */
|
/* Set to fetch the target tree. */
|
||||||
extern int get_tree;
|
extern int get_tree;
|
||||||
|
|
||||||
@ -46,6 +40,15 @@ extern int get_recover;
|
|||||||
/* Report what we got under get_verbosely */
|
/* Report what we got under get_verbosely */
|
||||||
extern void pull_say(const char *, const char *);
|
extern void pull_say(const char *, const char *);
|
||||||
|
|
||||||
extern int pull(char *target);
|
/* Load pull targets from stdin */
|
||||||
|
extern int pull_targets_stdin(char ***target, const char ***write_ref);
|
||||||
|
|
||||||
|
/* Free up loaded targets */
|
||||||
|
extern void pull_targets_free(int targets, char **target, const char **write_ref);
|
||||||
|
|
||||||
|
/* If write_ref is set, the ref filename to write the target value to. */
|
||||||
|
/* If write_ref_log_details is set, additional text will appear in the ref log. */
|
||||||
|
extern int pull(int targets, char **target, const char **write_ref,
|
||||||
|
const char *write_ref_log_details);
|
||||||
|
|
||||||
#endif /* PULL_H */
|
#endif /* PULL_H */
|
||||||
|
10
git-am.sh
10
git-am.sh
@ -91,6 +91,7 @@ fall_back_3way () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
prec=4
|
prec=4
|
||||||
|
rloga=am
|
||||||
dotest=.dotest sign= utf8= keep= skip= interactive= resolved= binary= ws= resolvemsg=
|
dotest=.dotest sign= utf8= keep= skip= interactive= resolved= binary= ws= resolvemsg=
|
||||||
|
|
||||||
while case "$#" in 0) break;; esac
|
while case "$#" in 0) break;; esac
|
||||||
@ -130,6 +131,9 @@ do
|
|||||||
--resolvemsg=*)
|
--resolvemsg=*)
|
||||||
resolvemsg=$(echo "$1" | sed -e "s/^--resolvemsg=//"); shift ;;
|
resolvemsg=$(echo "$1" | sed -e "s/^--resolvemsg=//"); shift ;;
|
||||||
|
|
||||||
|
--reflog-action=*)
|
||||||
|
rloga=`expr "z$1" : 'z-[^=]*=\(.*\)'`; shift ;;
|
||||||
|
|
||||||
--)
|
--)
|
||||||
shift; break ;;
|
shift; break ;;
|
||||||
-*)
|
-*)
|
||||||
@ -152,8 +156,10 @@ fi
|
|||||||
|
|
||||||
if test -d "$dotest"
|
if test -d "$dotest"
|
||||||
then
|
then
|
||||||
test ",$#," = ",0," ||
|
if test ",$#," != ",0," || ! tty -s
|
||||||
|
then
|
||||||
die "previous dotest directory $dotest still exists but mbox given."
|
die "previous dotest directory $dotest still exists but mbox given."
|
||||||
|
fi
|
||||||
resume=yes
|
resume=yes
|
||||||
else
|
else
|
||||||
# Make sure we are not given --skip nor --resolved
|
# Make sure we are not given --skip nor --resolved
|
||||||
@ -413,7 +419,7 @@ do
|
|||||||
parent=$(git-rev-parse --verify HEAD) &&
|
parent=$(git-rev-parse --verify HEAD) &&
|
||||||
commit=$(git-commit-tree $tree -p $parent <"$dotest/final-commit") &&
|
commit=$(git-commit-tree $tree -p $parent <"$dotest/final-commit") &&
|
||||||
echo Committed: $commit &&
|
echo Committed: $commit &&
|
||||||
git-update-ref -m "am: $SUBJECT" HEAD $commit $parent ||
|
git-update-ref -m "$rloga: $SUBJECT" HEAD $commit $parent ||
|
||||||
stop_here $this
|
stop_here $this
|
||||||
|
|
||||||
if test -x "$GIT_DIR"/hooks/post-applypatch
|
if test -x "$GIT_DIR"/hooks/post-applypatch
|
||||||
|
@ -266,7 +266,7 @@ yes,yes)
|
|||||||
echo "$repo/objects" >> "$GIT_DIR/objects/info/alternates"
|
echo "$repo/objects" >> "$GIT_DIR/objects/info/alternates"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD"
|
git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
case "$repo" in
|
case "$repo" in
|
||||||
@ -296,7 +296,7 @@ yes,yes)
|
|||||||
done
|
done
|
||||||
rm -f "$GIT_DIR/TMP_ALT"
|
rm -f "$GIT_DIR/TMP_ALT"
|
||||||
fi
|
fi
|
||||||
git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD"
|
git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1
|
||||||
;;
|
;;
|
||||||
http://*)
|
http://*)
|
||||||
if test -z "@@NO_CURL@@"
|
if test -z "@@NO_CURL@@"
|
||||||
|
@ -16,9 +16,9 @@ unless ($ENV{GIT_DIR} && -r $ENV{GIT_DIR}){
|
|||||||
die "GIT_DIR is not defined or is unreadable";
|
die "GIT_DIR is not defined or is unreadable";
|
||||||
}
|
}
|
||||||
|
|
||||||
our ($opt_h, $opt_p, $opt_v, $opt_c, $opt_f, $opt_m );
|
our ($opt_h, $opt_p, $opt_v, $opt_c, $opt_f, $opt_a, $opt_m );
|
||||||
|
|
||||||
getopts('hpvcfm:');
|
getopts('hpvcfam:');
|
||||||
|
|
||||||
$opt_h && usage();
|
$opt_h && usage();
|
||||||
|
|
||||||
@ -29,7 +29,6 @@ our ($tmpdir, $tmpdirname) = tempdir('git-cvsapplycommit-XXXXXX',
|
|||||||
TMPDIR => 1,
|
TMPDIR => 1,
|
||||||
CLEANUP => 1);
|
CLEANUP => 1);
|
||||||
|
|
||||||
print Dumper(@ARGV);
|
|
||||||
# resolve target commit
|
# resolve target commit
|
||||||
my $commit;
|
my $commit;
|
||||||
$commit = pop @ARGV;
|
$commit = pop @ARGV;
|
||||||
@ -53,12 +52,32 @@ if (@ARGV) {
|
|||||||
# find parents from the commit itself
|
# find parents from the commit itself
|
||||||
my @commit = safe_pipe_capture('git-cat-file', 'commit', $commit);
|
my @commit = safe_pipe_capture('git-cat-file', 'commit', $commit);
|
||||||
my @parents;
|
my @parents;
|
||||||
foreach my $p (@commit) {
|
my $committer;
|
||||||
if ($p =~ m/^$/) { # end of commit headers, we're done
|
my $author;
|
||||||
last;
|
my $stage = 'headers'; # headers, msg
|
||||||
|
my $title;
|
||||||
|
my $msg = '';
|
||||||
|
|
||||||
|
foreach my $line (@commit) {
|
||||||
|
chomp $line;
|
||||||
|
if ($stage eq 'headers' && $line eq '') {
|
||||||
|
$stage = 'msg';
|
||||||
|
next;
|
||||||
}
|
}
|
||||||
if ($p =~ m/^parent (\w{40})$/) { # found a parent
|
|
||||||
|
if ($stage eq 'headers') {
|
||||||
|
if ($line =~ m/^parent (\w{40})$/) { # found a parent
|
||||||
push @parents, $1;
|
push @parents, $1;
|
||||||
|
} elsif ($line =~ m/^author (.+) \d+ \+\d+$/) {
|
||||||
|
$author = $1;
|
||||||
|
} elsif ($line =~ m/^committer (.+) \d+ \+\d+$/) {
|
||||||
|
$committer = $1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$msg .= $line . "\n";
|
||||||
|
unless ($title) {
|
||||||
|
$title = $line;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,12 +103,18 @@ $opt_v && print "Applying to CVS commit $commit from parent $parent\n";
|
|||||||
|
|
||||||
# grab the commit message
|
# grab the commit message
|
||||||
open(MSG, ">.msg") or die "Cannot open .msg for writing";
|
open(MSG, ">.msg") or die "Cannot open .msg for writing";
|
||||||
|
if ($opt_m) {
|
||||||
print MSG $opt_m;
|
print MSG $opt_m;
|
||||||
|
}
|
||||||
|
print MSG $msg;
|
||||||
|
if ($opt_a) {
|
||||||
|
print MSG "\n\nAuthor: $author\n";
|
||||||
|
if ($author ne $committer) {
|
||||||
|
print MSG "Committer: $committer\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
close MSG;
|
close MSG;
|
||||||
|
|
||||||
`git-cat-file commit $commit | sed -e '1,/^\$/d' >> .msg`;
|
|
||||||
$? && die "Error extracting the commit message";
|
|
||||||
|
|
||||||
my (@afiles, @dfiles, @mfiles, @dirs);
|
my (@afiles, @dfiles, @mfiles, @dirs);
|
||||||
my @files = safe_pipe_capture('git-diff-tree', '-r', $parent, $commit);
|
my @files = safe_pipe_capture('git-diff-tree', '-r', $parent, $commit);
|
||||||
#print @files;
|
#print @files;
|
||||||
@ -233,6 +258,7 @@ foreach my $f (@dfiles) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
print "Commit to CVS\n";
|
print "Commit to CVS\n";
|
||||||
|
print "Patch: $title\n";
|
||||||
my $commitfiles = join(' ', @afiles, @mfiles, @dfiles);
|
my $commitfiles = join(' ', @afiles, @mfiles, @dfiles);
|
||||||
my $cmd = "cvs commit -F .msg $commitfiles";
|
my $cmd = "cvs commit -F .msg $commitfiles";
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ my $methods = {
|
|||||||
|
|
||||||
# $state holds all the bits of information the clients sends us that could
|
# $state holds all the bits of information the clients sends us that could
|
||||||
# potentially be useful when it comes to actually _doing_ something.
|
# potentially be useful when it comes to actually _doing_ something.
|
||||||
my $state = {};
|
my $state = { prependdir => '' };
|
||||||
$log->info("--------------- STARTING -----------------");
|
$log->info("--------------- STARTING -----------------");
|
||||||
|
|
||||||
my $TEMP_DIR = tempdir( CLEANUP => 1 );
|
my $TEMP_DIR = tempdir( CLEANUP => 1 );
|
||||||
@ -547,13 +547,16 @@ sub req_Argument
|
|||||||
{
|
{
|
||||||
my ( $cmd, $data ) = @_;
|
my ( $cmd, $data ) = @_;
|
||||||
|
|
||||||
# TODO : Not quite sure how Argument and Argumentx differ, but I assume
|
# Argumentx means: append to last Argument (with a newline in front)
|
||||||
# it's for multi-line arguments ... somehow ...
|
|
||||||
|
|
||||||
$log->debug("$cmd : $data");
|
$log->debug("$cmd : $data");
|
||||||
|
|
||||||
|
if ( $cmd eq 'Argumentx') {
|
||||||
|
${$state->{arguments}}[$#{$state->{arguments}}] .= "\n" . $data;
|
||||||
|
} else {
|
||||||
push @{$state->{arguments}}, $data;
|
push @{$state->{arguments}}, $data;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# expand-modules \n
|
# expand-modules \n
|
||||||
# Response expected: yes. Expand the modules which are specified in the
|
# Response expected: yes. Expand the modules which are specified in the
|
||||||
@ -1139,9 +1142,7 @@ sub req_ci
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
open FILE, ">", "$ENV{GIT_DIR}refs/heads/$state->{module}";
|
print LOCKFILE $commithash;
|
||||||
print FILE $commithash;
|
|
||||||
close FILE;
|
|
||||||
|
|
||||||
$updater->update();
|
$updater->update();
|
||||||
|
|
||||||
@ -1168,7 +1169,9 @@ sub req_ci
|
|||||||
}
|
}
|
||||||
|
|
||||||
close LOCKFILE;
|
close LOCKFILE;
|
||||||
unlink($lockfile);
|
my $reffile = "$ENV{GIT_DIR}refs/heads/$state->{module}";
|
||||||
|
unlink($reffile);
|
||||||
|
rename($lockfile, $reffile);
|
||||||
chdir "/";
|
chdir "/";
|
||||||
|
|
||||||
print "ok\n";
|
print "ok\n";
|
||||||
@ -2129,12 +2132,6 @@ sub update
|
|||||||
# first lets get the commit list
|
# first lets get the commit list
|
||||||
$ENV{GIT_DIR} = $self->{git_path};
|
$ENV{GIT_DIR} = $self->{git_path};
|
||||||
|
|
||||||
# prepare database queries
|
|
||||||
my $db_insert_rev = $self->{dbh}->prepare_cached("INSERT INTO revision (name, revision, filehash, commithash, modified, author, mode) VALUES (?,?,?,?,?,?,?)",{},1);
|
|
||||||
my $db_insert_mergelog = $self->{dbh}->prepare_cached("INSERT INTO commitmsgs (key, value) VALUES (?,?)",{},1);
|
|
||||||
my $db_delete_head = $self->{dbh}->prepare_cached("DELETE FROM head",{},1);
|
|
||||||
my $db_insert_head = $self->{dbh}->prepare_cached("INSERT INTO head (name, revision, filehash, commithash, modified, author, mode) VALUES (?,?,?,?,?,?,?)",{},1);
|
|
||||||
|
|
||||||
my $commitinfo = `git-cat-file commit $self->{module} 2>&1`;
|
my $commitinfo = `git-cat-file commit $self->{module} 2>&1`;
|
||||||
unless ( $commitinfo =~ /tree\s+[a-zA-Z0-9]{40}/ )
|
unless ( $commitinfo =~ /tree\s+[a-zA-Z0-9]{40}/ )
|
||||||
{
|
{
|
||||||
@ -2323,7 +2320,7 @@ sub update
|
|||||||
author => $commit->{author},
|
author => $commit->{author},
|
||||||
mode => $git_perms,
|
mode => $git_perms,
|
||||||
};
|
};
|
||||||
$db_insert_rev->execute($4, $head->{$4}{revision}, $2, $commit->{hash}, $commit->{date}, $commit->{author}, $git_perms);
|
$self->insert_rev($4, $head->{$4}{revision}, $2, $commit->{hash}, $commit->{date}, $commit->{author}, $git_perms);
|
||||||
}
|
}
|
||||||
elsif ( $3 eq "M" )
|
elsif ( $3 eq "M" )
|
||||||
{
|
{
|
||||||
@ -2337,7 +2334,7 @@ sub update
|
|||||||
author => $commit->{author},
|
author => $commit->{author},
|
||||||
mode => $git_perms,
|
mode => $git_perms,
|
||||||
};
|
};
|
||||||
$db_insert_rev->execute($4, $head->{$4}{revision}, $2, $commit->{hash}, $commit->{date}, $commit->{author}, $git_perms);
|
$self->insert_rev($4, $head->{$4}{revision}, $2, $commit->{hash}, $commit->{date}, $commit->{author}, $git_perms);
|
||||||
}
|
}
|
||||||
elsif ( $3 eq "A" )
|
elsif ( $3 eq "A" )
|
||||||
{
|
{
|
||||||
@ -2351,7 +2348,7 @@ sub update
|
|||||||
author => $commit->{author},
|
author => $commit->{author},
|
||||||
mode => $git_perms,
|
mode => $git_perms,
|
||||||
};
|
};
|
||||||
$db_insert_rev->execute($4, $head->{$4}{revision}, $2, $commit->{hash}, $commit->{date}, $commit->{author}, $git_perms);
|
$self->insert_rev($4, $head->{$4}{revision}, $2, $commit->{hash}, $commit->{date}, $commit->{author}, $git_perms);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2408,7 +2405,7 @@ sub update
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
$db_insert_rev->execute($git_filename, $newrevision, $git_hash, $commit->{hash}, $commit->{date}, $commit->{author}, $git_perms);
|
$self->insert_rev($git_filename, $newrevision, $git_hash, $commit->{hash}, $commit->{date}, $commit->{author}, $git_perms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close FILELIST;
|
close FILELIST;
|
||||||
@ -2424,7 +2421,7 @@ sub update
|
|||||||
$head->{$file}{modified} = $commit->{date};
|
$head->{$file}{modified} = $commit->{date};
|
||||||
$head->{$file}{author} = $commit->{author};
|
$head->{$file}{author} = $commit->{author};
|
||||||
|
|
||||||
$db_insert_rev->execute($file, $head->{$file}{revision}, $head->{$file}{filehash}, $commit->{hash}, $commit->{date}, $commit->{author}, $head->{$file}{mode});
|
$self->insert_rev($file, $head->{$file}{revision}, $head->{$file}{filehash}, $commit->{hash}, $commit->{date}, $commit->{author}, $head->{$file}{mode});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# END : "Detect deleted files"
|
# END : "Detect deleted files"
|
||||||
@ -2433,7 +2430,7 @@ sub update
|
|||||||
|
|
||||||
if (exists $commit->{mergemsg})
|
if (exists $commit->{mergemsg})
|
||||||
{
|
{
|
||||||
$db_insert_mergelog->execute($commit->{hash}, $commit->{mergemsg});
|
$self->insert_mergelog($commit->{hash}, $commit->{mergemsg});
|
||||||
}
|
}
|
||||||
|
|
||||||
$lastpicked = $commit->{hash};
|
$lastpicked = $commit->{hash};
|
||||||
@ -2441,10 +2438,10 @@ sub update
|
|||||||
$self->_set_prop("last_commit", $commit->{hash});
|
$self->_set_prop("last_commit", $commit->{hash});
|
||||||
}
|
}
|
||||||
|
|
||||||
$db_delete_head->execute();
|
$self->delete_head();
|
||||||
foreach my $file ( keys %$head )
|
foreach my $file ( keys %$head )
|
||||||
{
|
{
|
||||||
$db_insert_head->execute(
|
$self->insert_head(
|
||||||
$file,
|
$file,
|
||||||
$head->{$file}{revision},
|
$head->{$file}{revision},
|
||||||
$head->{$file}{filehash},
|
$head->{$file}{filehash},
|
||||||
@ -2462,6 +2459,54 @@ sub update
|
|||||||
$self->{dbh}->commit() or die "Failed to commit changes to SQLite";
|
$self->{dbh}->commit() or die "Failed to commit changes to SQLite";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub insert_rev
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
my $name = shift;
|
||||||
|
my $revision = shift;
|
||||||
|
my $filehash = shift;
|
||||||
|
my $commithash = shift;
|
||||||
|
my $modified = shift;
|
||||||
|
my $author = shift;
|
||||||
|
my $mode = shift;
|
||||||
|
|
||||||
|
my $insert_rev = $self->{dbh}->prepare_cached("INSERT INTO revision (name, revision, filehash, commithash, modified, author, mode) VALUES (?,?,?,?,?,?,?)",{},1);
|
||||||
|
$insert_rev->execute($name, $revision, $filehash, $commithash, $modified, $author, $mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub insert_mergelog
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
my $key = shift;
|
||||||
|
my $value = shift;
|
||||||
|
|
||||||
|
my $insert_mergelog = $self->{dbh}->prepare_cached("INSERT INTO commitmsgs (key, value) VALUES (?,?)",{},1);
|
||||||
|
$insert_mergelog->execute($key, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub delete_head
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
my $delete_head = $self->{dbh}->prepare_cached("DELETE FROM head",{},1);
|
||||||
|
$delete_head->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
sub insert_head
|
||||||
|
{
|
||||||
|
my $self = shift;
|
||||||
|
my $name = shift;
|
||||||
|
my $revision = shift;
|
||||||
|
my $filehash = shift;
|
||||||
|
my $commithash = shift;
|
||||||
|
my $modified = shift;
|
||||||
|
my $author = shift;
|
||||||
|
my $mode = shift;
|
||||||
|
|
||||||
|
my $insert_head = $self->{dbh}->prepare_cached("INSERT INTO head (name, revision, filehash, commithash, modified, author, mode) VALUES (?,?,?,?,?,?,?)",{},1);
|
||||||
|
$insert_head->execute($name, $revision, $filehash, $commithash, $modified, $author, $mode);
|
||||||
|
}
|
||||||
|
|
||||||
sub _headrev
|
sub _headrev
|
||||||
{
|
{
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
17
git-fetch.sh
17
git-fetch.sh
@ -20,6 +20,7 @@ verbose=
|
|||||||
update_head_ok=
|
update_head_ok=
|
||||||
exec=
|
exec=
|
||||||
upload_pack=
|
upload_pack=
|
||||||
|
keep=--thin
|
||||||
while case "$#" in 0) break ;; esac
|
while case "$#" in 0) break ;; esac
|
||||||
do
|
do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
@ -69,6 +70,7 @@ case "$#" in
|
|||||||
0)
|
0)
|
||||||
test -f "$GIT_DIR/branches/origin" ||
|
test -f "$GIT_DIR/branches/origin" ||
|
||||||
test -f "$GIT_DIR/remotes/origin" ||
|
test -f "$GIT_DIR/remotes/origin" ||
|
||||||
|
git-repo-config --get remote.origin.url >/dev/null ||
|
||||||
die "Where do you want to fetch from today?"
|
die "Where do you want to fetch from today?"
|
||||||
set origin ;;
|
set origin ;;
|
||||||
esac
|
esac
|
||||||
@ -153,7 +155,7 @@ fast_forward_local () {
|
|||||||
then
|
then
|
||||||
if now_=$(cat "$GIT_DIR/$1") && test "$now_" = "$2"
|
if now_=$(cat "$GIT_DIR/$1") && test "$now_" = "$2"
|
||||||
then
|
then
|
||||||
[ "$verbose" ] && echo >&2 "* $1: same as $3"
|
[ "$verbose" ] && echo >&2 "* $1: same as $3" ||:
|
||||||
else
|
else
|
||||||
echo >&2 "* $1: updating with $3"
|
echo >&2 "* $1: updating with $3"
|
||||||
git-update-ref -m "$rloga: updating tag" "$1" "$2"
|
git-update-ref -m "$rloga: updating tag" "$1" "$2"
|
||||||
@ -223,9 +225,16 @@ reflist=$(get_remote_refs_for_fetch "$@")
|
|||||||
if test "$tags"
|
if test "$tags"
|
||||||
then
|
then
|
||||||
taglist=`IFS=" " &&
|
taglist=`IFS=" " &&
|
||||||
git-ls-remote $upload_pack --tags "$remote" |
|
(
|
||||||
|
git-ls-remote $upload_pack --tags "$remote" ||
|
||||||
|
echo fail ouch
|
||||||
|
) |
|
||||||
while read sha1 name
|
while read sha1 name
|
||||||
do
|
do
|
||||||
|
case "$sha1" in
|
||||||
|
fail)
|
||||||
|
exit 1
|
||||||
|
esac
|
||||||
case "$name" in
|
case "$name" in
|
||||||
*^*) continue ;;
|
*^*) continue ;;
|
||||||
esac
|
esac
|
||||||
@ -235,7 +244,7 @@ then
|
|||||||
else
|
else
|
||||||
echo >&2 "warning: tag ${name} ignored"
|
echo >&2 "warning: tag ${name} ignored"
|
||||||
fi
|
fi
|
||||||
done`
|
done` || exit
|
||||||
if test "$#" -gt 1
|
if test "$#" -gt 1
|
||||||
then
|
then
|
||||||
# remote URL plus explicit refspecs; we need to merge them.
|
# remote URL plus explicit refspecs; we need to merge them.
|
||||||
@ -347,7 +356,7 @@ fetch_main () {
|
|||||||
( : subshell because we muck with IFS
|
( : subshell because we muck with IFS
|
||||||
IFS=" $LF"
|
IFS=" $LF"
|
||||||
(
|
(
|
||||||
git-fetch-pack $exec $keep --thin "$remote" $rref || echo failed "$remote"
|
git-fetch-pack $exec $keep "$remote" $rref || echo failed "$remote"
|
||||||
) |
|
) |
|
||||||
while read sha1 remote_name
|
while read sha1 remote_name
|
||||||
do
|
do
|
||||||
|
@ -54,6 +54,10 @@ start_httpd () {
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
if test $? != 0; then
|
||||||
|
echo "Could not execute http daemon $httpd."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
stop_httpd () {
|
stop_httpd () {
|
||||||
@ -183,8 +187,10 @@ PerlPassEnv GIT_EXEC_DIR
|
|||||||
EOF
|
EOF
|
||||||
else
|
else
|
||||||
# plain-old CGI
|
# plain-old CGI
|
||||||
|
list_mods=`echo "$httpd" | sed "s/-f$/-l/"`
|
||||||
|
$list_mods | grep 'mod_cgi\.c' >/dev/null 2>&1 || \
|
||||||
|
echo "LoadModule cgi_module $module_path/mod_cgi.so" >> "$conf"
|
||||||
cat >> "$conf" <<EOF
|
cat >> "$conf" <<EOF
|
||||||
LoadModule cgi_module $module_path/mod_cgi.so
|
|
||||||
AddHandler cgi-script .cgi
|
AddHandler cgi-script .cgi
|
||||||
<Location /gitweb.cgi>
|
<Location /gitweb.cgi>
|
||||||
Options +ExecCGI
|
Options +ExecCGI
|
||||||
@ -232,4 +238,5 @@ esac
|
|||||||
|
|
||||||
start_httpd
|
start_httpd
|
||||||
test -z "$browser" && browser=echo
|
test -z "$browser" && browser=echo
|
||||||
$browser http://127.0.0.1:$port
|
url=http://127.0.0.1:$port
|
||||||
|
$browser $url || echo $url
|
||||||
|
@ -12,7 +12,7 @@ fi
|
|||||||
laf="$GIT_DIR/lost-found"
|
laf="$GIT_DIR/lost-found"
|
||||||
rm -fr "$laf" && mkdir -p "$laf/commit" "$laf/other" || exit
|
rm -fr "$laf" && mkdir -p "$laf/commit" "$laf/other" || exit
|
||||||
|
|
||||||
git fsck-objects |
|
git fsck-objects --full |
|
||||||
while read dangling type sha1
|
while read dangling type sha1
|
||||||
do
|
do
|
||||||
case "$dangling" in
|
case "$dangling" in
|
||||||
|
17
git-merge.sh
17
git-merge.sh
@ -63,7 +63,13 @@ squash_message () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
finish () {
|
finish () {
|
||||||
test '' = "$2" || echo "$2"
|
if test '' = "$2"
|
||||||
|
then
|
||||||
|
rlogm="$rloga"
|
||||||
|
else
|
||||||
|
echo "$2"
|
||||||
|
rlogm="$rloga: $2"
|
||||||
|
fi
|
||||||
case "$squash" in
|
case "$squash" in
|
||||||
t)
|
t)
|
||||||
echo "Squash commit -- not updating HEAD"
|
echo "Squash commit -- not updating HEAD"
|
||||||
@ -75,7 +81,7 @@ finish () {
|
|||||||
echo "No merge message -- not updating HEAD"
|
echo "No merge message -- not updating HEAD"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
git-update-ref HEAD "$1" "$head" || exit 1
|
git-update-ref -m "$rlogm" HEAD "$1" "$head" || exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
@ -93,6 +99,7 @@ finish () {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rloga=
|
||||||
while case "$#" in 0) break ;; esac
|
while case "$#" in 0) break ;; esac
|
||||||
do
|
do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
@ -126,6 +133,9 @@ do
|
|||||||
die "available strategies are: $all_strategies" ;;
|
die "available strategies are: $all_strategies" ;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
|
--reflog-action=*)
|
||||||
|
rloga=`expr "z$1" : 'z-[^=]*=\(.*\)'`
|
||||||
|
;;
|
||||||
-*) usage ;;
|
-*) usage ;;
|
||||||
*) break ;;
|
*) break ;;
|
||||||
esac
|
esac
|
||||||
@ -140,6 +150,7 @@ shift
|
|||||||
|
|
||||||
# All the rest are remote heads
|
# All the rest are remote heads
|
||||||
test "$#" = 0 && usage ;# we need at least one remote head.
|
test "$#" = 0 && usage ;# we need at least one remote head.
|
||||||
|
test "$rloga" = '' && rloga="merge: $@"
|
||||||
|
|
||||||
remoteheads=
|
remoteheads=
|
||||||
for remote
|
for remote
|
||||||
@ -325,7 +336,7 @@ if test '' != "$result_tree"
|
|||||||
then
|
then
|
||||||
parents=$(git-show-branch --independent "$head" "$@" | sed -e 's/^/-p /')
|
parents=$(git-show-branch --independent "$head" "$@" | sed -e 's/^/-p /')
|
||||||
result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree $parents) || exit
|
result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree $parents) || exit
|
||||||
finish "$result_commit" "Merge $result_commit, made by $wt_strategy."
|
finish "$result_commit" "Merge made by $wt_strategy."
|
||||||
dropsave
|
dropsave
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
250
git-mv.perl
250
git-mv.perl
@ -1,250 +0,0 @@
|
|||||||
#!/usr/bin/perl
|
|
||||||
#
|
|
||||||
# Copyright 2005, Ryan Anderson <ryan@michonline.com>
|
|
||||||
# Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
|
|
||||||
#
|
|
||||||
# This file is licensed under the GPL v2, or a later version
|
|
||||||
# at the discretion of Linus Torvalds.
|
|
||||||
|
|
||||||
|
|
||||||
use warnings;
|
|
||||||
use strict;
|
|
||||||
use Getopt::Std;
|
|
||||||
|
|
||||||
sub usage() {
|
|
||||||
print <<EOT;
|
|
||||||
$0 [-f] [-n] <source> <destination>
|
|
||||||
$0 [-f] [-n] [-k] <source> ... <destination directory>
|
|
||||||
EOT
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
our ($opt_n, $opt_f, $opt_h, $opt_k, $opt_v);
|
|
||||||
getopts("hnfkv") || usage;
|
|
||||||
usage() if $opt_h;
|
|
||||||
@ARGV >= 1 or usage;
|
|
||||||
|
|
||||||
my $GIT_DIR = `git rev-parse --git-dir`;
|
|
||||||
exit 1 if $?; # rev-parse would have given "not a git dir" message.
|
|
||||||
chomp($GIT_DIR);
|
|
||||||
|
|
||||||
my (@srcArgs, @dstArgs, @srcs, @dsts);
|
|
||||||
my ($src, $dst, $base, $dstDir);
|
|
||||||
|
|
||||||
# remove any trailing slash in arguments
|
|
||||||
for (@ARGV) { s/\/*$//; }
|
|
||||||
|
|
||||||
my $argCount = scalar @ARGV;
|
|
||||||
if (-d $ARGV[$argCount-1]) {
|
|
||||||
$dstDir = $ARGV[$argCount-1];
|
|
||||||
@srcArgs = @ARGV[0..$argCount-2];
|
|
||||||
|
|
||||||
foreach $src (@srcArgs) {
|
|
||||||
$base = $src;
|
|
||||||
$base =~ s/^.*\///;
|
|
||||||
$dst = "$dstDir/". $base;
|
|
||||||
push @dstArgs, $dst;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ($argCount < 2) {
|
|
||||||
print "Error: need at least two arguments\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if ($argCount > 2) {
|
|
||||||
print "Error: moving to directory '"
|
|
||||||
. $ARGV[$argCount-1]
|
|
||||||
. "' not possible; not existing\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
@srcArgs = ($ARGV[0]);
|
|
||||||
@dstArgs = ($ARGV[1]);
|
|
||||||
$dstDir = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
my $subdir_prefix = `git rev-parse --show-prefix`;
|
|
||||||
chomp($subdir_prefix);
|
|
||||||
|
|
||||||
# run in git base directory, so that git-ls-files lists all revisioned files
|
|
||||||
chdir "$GIT_DIR/..";
|
|
||||||
|
|
||||||
# normalize paths, needed to compare against versioned files and update-index
|
|
||||||
# also, this is nicer to end-users by doing ".//a/./b/.//./c" ==> "a/b/c"
|
|
||||||
for (@srcArgs, @dstArgs) {
|
|
||||||
# prepend git prefix as we run from base directory
|
|
||||||
$_ = $subdir_prefix.$_;
|
|
||||||
s|^\./||;
|
|
||||||
s|/\./|/| while (m|/\./|);
|
|
||||||
s|//+|/|g;
|
|
||||||
# Also "a/b/../c" ==> "a/c"
|
|
||||||
1 while (s,(^|/)[^/]+/\.\./,$1,);
|
|
||||||
}
|
|
||||||
|
|
||||||
my (@allfiles,@srcfiles,@dstfiles);
|
|
||||||
my $safesrc;
|
|
||||||
my (%overwritten, %srcForDst);
|
|
||||||
|
|
||||||
$/ = "\0";
|
|
||||||
open(F, 'git-ls-files -z |')
|
|
||||||
or die "Failed to open pipe from git-ls-files: " . $!;
|
|
||||||
|
|
||||||
@allfiles = map { chomp; $_; } <F>;
|
|
||||||
close(F);
|
|
||||||
|
|
||||||
|
|
||||||
my ($i, $bad);
|
|
||||||
while(scalar @srcArgs > 0) {
|
|
||||||
$src = shift @srcArgs;
|
|
||||||
$dst = shift @dstArgs;
|
|
||||||
$bad = "";
|
|
||||||
|
|
||||||
for ($src, $dst) {
|
|
||||||
# Be nicer to end-users by doing ".//a/./b/.//./c" ==> "a/b/c"
|
|
||||||
s|^\./||;
|
|
||||||
s|/\./|/| while (m|/\./|);
|
|
||||||
s|//+|/|g;
|
|
||||||
# Also "a/b/../c" ==> "a/c"
|
|
||||||
1 while (s,(^|/)[^/]+/\.\./,$1,);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($opt_v) {
|
|
||||||
print "Checking rename of '$src' to '$dst'\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
unless (-f $src || -l $src || -d $src) {
|
|
||||||
$bad = "bad source '$src'";
|
|
||||||
}
|
|
||||||
|
|
||||||
$safesrc = quotemeta($src);
|
|
||||||
@srcfiles = grep /^$safesrc(\/|$)/, @allfiles;
|
|
||||||
|
|
||||||
$overwritten{$dst} = 0;
|
|
||||||
if (($bad eq "") && -e $dst) {
|
|
||||||
$bad = "destination '$dst' already exists";
|
|
||||||
if ($opt_f) {
|
|
||||||
# only files can overwrite each other: check both source and destination
|
|
||||||
if (-f $dst && (scalar @srcfiles == 1)) {
|
|
||||||
print "Warning: $bad; will overwrite!\n";
|
|
||||||
$bad = "";
|
|
||||||
$overwritten{$dst} = 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$bad = "Can not overwrite '$src' with '$dst'";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (($bad eq "") && ($dst =~ /^$safesrc\//)) {
|
|
||||||
$bad = "can not move directory '$src' into itself";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($bad eq "") {
|
|
||||||
if (scalar @srcfiles == 0) {
|
|
||||||
$bad = "'$src' not under version control";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($bad eq "") {
|
|
||||||
if (defined $srcForDst{$dst}) {
|
|
||||||
$bad = "can not move '$src' to '$dst'; already target of ";
|
|
||||||
$bad .= "'".$srcForDst{$dst}."'";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$srcForDst{$dst} = $src;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($bad ne "") {
|
|
||||||
if ($opt_k) {
|
|
||||||
print "Warning: $bad; skipping\n";
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
print "Error: $bad\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
push @srcs, $src;
|
|
||||||
push @dsts, $dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Final pass: rename/move
|
|
||||||
my (@deletedfiles,@addedfiles,@changedfiles);
|
|
||||||
$bad = "";
|
|
||||||
while(scalar @srcs > 0) {
|
|
||||||
$src = shift @srcs;
|
|
||||||
$dst = shift @dsts;
|
|
||||||
|
|
||||||
if ($opt_n || $opt_v) { print "Renaming $src to $dst\n"; }
|
|
||||||
if (!$opt_n) {
|
|
||||||
if (!rename($src,$dst)) {
|
|
||||||
$bad = "renaming '$src' failed: $!";
|
|
||||||
if ($opt_k) {
|
|
||||||
print "Warning: skipped: $bad\n";
|
|
||||||
$bad = "";
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
last;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$safesrc = quotemeta($src);
|
|
||||||
@srcfiles = grep /^$safesrc(\/|$)/, @allfiles;
|
|
||||||
@dstfiles = @srcfiles;
|
|
||||||
s/^$safesrc(\/|$)/$dst$1/ for @dstfiles;
|
|
||||||
|
|
||||||
push @deletedfiles, @srcfiles;
|
|
||||||
if (scalar @srcfiles == 1) {
|
|
||||||
# $dst can be a directory with 1 file inside
|
|
||||||
if ($overwritten{$dst} ==1) {
|
|
||||||
push @changedfiles, $dstfiles[0];
|
|
||||||
|
|
||||||
} else {
|
|
||||||
push @addedfiles, $dstfiles[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
push @addedfiles, @dstfiles;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($opt_n) {
|
|
||||||
if (@changedfiles) {
|
|
||||||
print "Changed : ". join(", ", @changedfiles) ."\n";
|
|
||||||
}
|
|
||||||
if (@addedfiles) {
|
|
||||||
print "Adding : ". join(", ", @addedfiles) ."\n";
|
|
||||||
}
|
|
||||||
if (@deletedfiles) {
|
|
||||||
print "Deleting : ". join(", ", @deletedfiles) ."\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (@changedfiles) {
|
|
||||||
open(H, "| git-update-index -z --stdin")
|
|
||||||
or die "git-update-index failed to update changed files with code $!\n";
|
|
||||||
foreach my $fileName (@changedfiles) {
|
|
||||||
print H "$fileName\0";
|
|
||||||
}
|
|
||||||
close(H);
|
|
||||||
}
|
|
||||||
if (@addedfiles) {
|
|
||||||
open(H, "| git-update-index --add -z --stdin")
|
|
||||||
or die "git-update-index failed to add new names with code $!\n";
|
|
||||||
foreach my $fileName (@addedfiles) {
|
|
||||||
print H "$fileName\0";
|
|
||||||
}
|
|
||||||
close(H);
|
|
||||||
}
|
|
||||||
if (@deletedfiles) {
|
|
||||||
open(H, "| git-update-index --remove -z --stdin")
|
|
||||||
or die "git-update-index failed to remove old names with code $!\n";
|
|
||||||
foreach my $fileName (@deletedfiles) {
|
|
||||||
print H "$fileName\0";
|
|
||||||
}
|
|
||||||
close(H);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($bad ne "") {
|
|
||||||
print "Error: $bad\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
@ -102,5 +102,6 @@ case "$strategy_args" in
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
merge_name=$(git-fmt-merge-msg <"$GIT_DIR/FETCH_HEAD") || exit
|
merge_name=$(git-fmt-merge-msg <"$GIT_DIR/FETCH_HEAD") || exit
|
||||||
git-merge $no_summary $no_commit $squash $strategy_args \
|
git-merge "--reflog-action=pull $*" \
|
||||||
|
$no_summary $no_commit $squash $strategy_args \
|
||||||
"$merge_name" HEAD $merge_head
|
"$merge_name" HEAD $merge_head
|
||||||
|
@ -112,7 +112,7 @@ for patch_name in $(cat "$QUILT_PATCHES/series" | grep -v '^#'); do
|
|||||||
git-apply --index -C1 "$tmp_patch" &&
|
git-apply --index -C1 "$tmp_patch" &&
|
||||||
tree=$(git-write-tree) &&
|
tree=$(git-write-tree) &&
|
||||||
commit=$((echo "$SUBJECT"; echo; cat "$tmp_msg") | git-commit-tree $tree -p $commit) &&
|
commit=$((echo "$SUBJECT"; echo; cat "$tmp_msg") | git-commit-tree $tree -p $commit) &&
|
||||||
git-update-ref HEAD $commit || exit 4
|
git-update-ref -m "quiltimport: $patch_name" HEAD $commit || exit 4
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
rm -rf $tmp_dir || exit 5
|
rm -rf $tmp_dir || exit 5
|
||||||
|
@ -137,7 +137,8 @@ do
|
|||||||
finish_rb_merge
|
finish_rb_merge
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
git am --resolved --3way --resolvemsg="$RESOLVEMSG"
|
git am --resolved --3way --resolvemsg="$RESOLVEMSG" \
|
||||||
|
--reflog-action=rebase
|
||||||
exit
|
exit
|
||||||
;;
|
;;
|
||||||
--skip)
|
--skip)
|
||||||
@ -156,7 +157,8 @@ do
|
|||||||
finish_rb_merge
|
finish_rb_merge
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
git am -3 --skip --resolvemsg="$RESOLVEMSG"
|
git am -3 --skip --resolvemsg="$RESOLVEMSG" \
|
||||||
|
--reflog-action=rebase
|
||||||
exit
|
exit
|
||||||
;;
|
;;
|
||||||
--abort)
|
--abort)
|
||||||
@ -299,7 +301,8 @@ fi
|
|||||||
if test -z "$do_merge"
|
if test -z "$do_merge"
|
||||||
then
|
then
|
||||||
git-format-patch -k --stdout --full-index "$upstream"..ORIG_HEAD |
|
git-format-patch -k --stdout --full-index "$upstream"..ORIG_HEAD |
|
||||||
git am --binary -3 -k --resolvemsg="$RESOLVEMSG"
|
git am --binary -3 -k --resolvemsg="$RESOLVEMSG" \
|
||||||
|
--reflog-action=rebase
|
||||||
exit $?
|
exit $?
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -52,7 +52,8 @@ then
|
|||||||
else
|
else
|
||||||
rm -f "$GIT_DIR/ORIG_HEAD"
|
rm -f "$GIT_DIR/ORIG_HEAD"
|
||||||
fi
|
fi
|
||||||
git-update-ref -m "reset $reset_type $@" HEAD "$rev"
|
git-update-ref -m "reset $reset_type $*" HEAD "$rev"
|
||||||
|
update_ref_status=$?
|
||||||
|
|
||||||
case "$reset_type" in
|
case "$reset_type" in
|
||||||
--hard )
|
--hard )
|
||||||
@ -66,3 +67,5 @@ case "$reset_type" in
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
rm -f "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/rr-cache/MERGE_RR" "$GIT_DIR/SQUASH_MSG"
|
rm -f "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/rr-cache/MERGE_RR" "$GIT_DIR/SQUASH_MSG"
|
||||||
|
|
||||||
|
exit $update_ref_status
|
||||||
|
@ -15,6 +15,7 @@ dropheads() {
|
|||||||
|
|
||||||
head=$(git-rev-parse --verify "$1"^0) &&
|
head=$(git-rev-parse --verify "$1"^0) &&
|
||||||
merge=$(git-rev-parse --verify "$2"^0) &&
|
merge=$(git-rev-parse --verify "$2"^0) &&
|
||||||
|
merge_name="$2" &&
|
||||||
merge_msg="$3" || usage
|
merge_msg="$3" || usage
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -43,7 +44,8 @@ case "$common" in
|
|||||||
"$head")
|
"$head")
|
||||||
echo "Updating from $head to $merge"
|
echo "Updating from $head to $merge"
|
||||||
git-read-tree -u -m $head $merge || exit 1
|
git-read-tree -u -m $head $merge || exit 1
|
||||||
git-update-ref HEAD "$merge" "$head"
|
git-update-ref -m "resolve $merge_name: Fast forward" \
|
||||||
|
HEAD "$merge" "$head"
|
||||||
git-diff-tree -p $head $merge | git-apply --stat
|
git-diff-tree -p $head $merge | git-apply --stat
|
||||||
dropheads
|
dropheads
|
||||||
exit 0
|
exit 0
|
||||||
@ -100,6 +102,7 @@ if [ $? -ne 0 ]; then
|
|||||||
fi
|
fi
|
||||||
result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree -p $head -p $merge)
|
result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree -p $head -p $merge)
|
||||||
echo "Committed merge $result_commit"
|
echo "Committed merge $result_commit"
|
||||||
git-update-ref HEAD "$result_commit" "$head"
|
git-update-ref -m "resolve $merge_name: In-index merge" \
|
||||||
|
HEAD "$result_commit" "$head"
|
||||||
git-diff-tree -p $head $result_commit | git-apply --stat
|
git-diff-tree -p $head $result_commit | git-apply --stat
|
||||||
dropheads
|
dropheads
|
||||||
|
25
git-svn.perl
25
git-svn.perl
@ -147,7 +147,7 @@ init_vars();
|
|||||||
load_authors() if $_authors;
|
load_authors() if $_authors;
|
||||||
load_all_refs() if $_branch_all_refs;
|
load_all_refs() if $_branch_all_refs;
|
||||||
svn_compat_check() unless $_use_lib;
|
svn_compat_check() unless $_use_lib;
|
||||||
migration_check() unless $cmd =~ /^(?:init|rebuild|multi-init)$/;
|
migration_check() unless $cmd =~ /^(?:init|rebuild|multi-init|commit-diff)$/;
|
||||||
$cmd{$cmd}->[0]->(@ARGV);
|
$cmd{$cmd}->[0]->(@ARGV);
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
||||||
@ -2709,6 +2709,12 @@ sub libsvn_fetch {
|
|||||||
} else {
|
} else {
|
||||||
die "Unrecognized action: $m, ($f r$rev)\n";
|
die "Unrecognized action: $m, ($f r$rev)\n";
|
||||||
}
|
}
|
||||||
|
} elsif ($t == $SVN::Node::dir && $m =~ /^[AR]$/) {
|
||||||
|
my @traversed = ();
|
||||||
|
libsvn_traverse($gui, '', $f, $rev, \@traversed);
|
||||||
|
foreach (@traversed) {
|
||||||
|
push @amr, [ $m, $_ ]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$pool->clear;
|
$pool->clear;
|
||||||
}
|
}
|
||||||
@ -2778,7 +2784,7 @@ sub libsvn_parse_revision {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub libsvn_traverse {
|
sub libsvn_traverse {
|
||||||
my ($gui, $pfx, $path, $rev) = @_;
|
my ($gui, $pfx, $path, $rev, $files) = @_;
|
||||||
my $cwd = "$pfx/$path";
|
my $cwd = "$pfx/$path";
|
||||||
my $pool = SVN::Pool->new;
|
my $pool = SVN::Pool->new;
|
||||||
$cwd =~ s#^/+##g;
|
$cwd =~ s#^/+##g;
|
||||||
@ -2786,10 +2792,15 @@ sub libsvn_traverse {
|
|||||||
foreach my $d (keys %$dirent) {
|
foreach my $d (keys %$dirent) {
|
||||||
my $t = $dirent->{$d}->kind;
|
my $t = $dirent->{$d}->kind;
|
||||||
if ($t == $SVN::Node::dir) {
|
if ($t == $SVN::Node::dir) {
|
||||||
libsvn_traverse($gui, $cwd, $d, $rev);
|
libsvn_traverse($gui, $cwd, $d, $rev, $files);
|
||||||
} elsif ($t == $SVN::Node::file) {
|
} elsif ($t == $SVN::Node::file) {
|
||||||
print "\tA\t$cwd/$d\n" unless $_q;
|
my $file = "$cwd/$d";
|
||||||
libsvn_get_file($gui, "$cwd/$d", $rev);
|
if (defined $files) {
|
||||||
|
push @$files, $file;
|
||||||
|
} else {
|
||||||
|
print "\tA\t$file\n" unless $_q;
|
||||||
|
libsvn_get_file($gui, $file, $rev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$pool->clear;
|
$pool->clear;
|
||||||
@ -2913,9 +2924,7 @@ sub libsvn_new_tree {
|
|||||||
}
|
}
|
||||||
my ($paths, $rev, $author, $date, $msg) = @_;
|
my ($paths, $rev, $author, $date, $msg) = @_;
|
||||||
open my $gui, '| git-update-index -z --index-info' or croak $!;
|
open my $gui, '| git-update-index -z --index-info' or croak $!;
|
||||||
my $pool = SVN::Pool->new;
|
libsvn_traverse($gui, '', $SVN_PATH, $rev);
|
||||||
libsvn_traverse($gui, '', $SVN_PATH, $rev, $pool);
|
|
||||||
$pool->clear;
|
|
||||||
close $gui or croak $?;
|
close $gui or croak $?;
|
||||||
return libsvn_log_entry($rev, $author, $date, $msg);
|
return libsvn_log_entry($rev, $author, $date, $msg);
|
||||||
}
|
}
|
||||||
|
190
git.c
190
git.c
@ -35,6 +35,59 @@ static void prepend_to_path(const char *dir, int len)
|
|||||||
setenv("PATH", path, 1);
|
setenv("PATH", path, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int handle_options(const char*** argv, int* argc)
|
||||||
|
{
|
||||||
|
int handled = 0;
|
||||||
|
|
||||||
|
while (*argc > 0) {
|
||||||
|
const char *cmd = (*argv)[0];
|
||||||
|
if (cmd[0] != '-')
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For legacy reasons, the "version" and "help"
|
||||||
|
* commands can be written with "--" prepended
|
||||||
|
* to make them look like flags.
|
||||||
|
*/
|
||||||
|
if (!strcmp(cmd, "--help") || !strcmp(cmd, "--version"))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check remaining flags.
|
||||||
|
*/
|
||||||
|
if (!strncmp(cmd, "--exec-path", 11)) {
|
||||||
|
cmd += 11;
|
||||||
|
if (*cmd == '=')
|
||||||
|
git_set_exec_path(cmd + 1);
|
||||||
|
else {
|
||||||
|
puts(git_exec_path());
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
} else if (!strcmp(cmd, "-p") || !strcmp(cmd, "--paginate")) {
|
||||||
|
setup_pager();
|
||||||
|
} else if (!strcmp(cmd, "--git-dir")) {
|
||||||
|
if (*argc < 1)
|
||||||
|
return -1;
|
||||||
|
setenv("GIT_DIR", (*argv)[1], 1);
|
||||||
|
(*argv)++;
|
||||||
|
(*argc)--;
|
||||||
|
} else if (!strncmp(cmd, "--git-dir=", 10)) {
|
||||||
|
setenv("GIT_DIR", cmd + 10, 1);
|
||||||
|
} else if (!strcmp(cmd, "--bare")) {
|
||||||
|
static char git_dir[1024];
|
||||||
|
setenv("GIT_DIR", getcwd(git_dir, 1024), 1);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Unknown option: %s\n", cmd);
|
||||||
|
cmd_usage(0, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
(*argv)++;
|
||||||
|
(*argc)--;
|
||||||
|
handled++;
|
||||||
|
}
|
||||||
|
return handled;
|
||||||
|
}
|
||||||
|
|
||||||
static const char *alias_command;
|
static const char *alias_command;
|
||||||
static char *alias_string = NULL;
|
static char *alias_string = NULL;
|
||||||
|
|
||||||
@ -103,17 +156,19 @@ static int handle_alias(int *argcp, const char ***argv)
|
|||||||
{
|
{
|
||||||
int nongit = 0, ret = 0, saved_errno = errno;
|
int nongit = 0, ret = 0, saved_errno = errno;
|
||||||
const char *subdir;
|
const char *subdir;
|
||||||
|
int count, option_count;
|
||||||
|
const char** new_argv;
|
||||||
|
|
||||||
subdir = setup_git_directory_gently(&nongit);
|
subdir = setup_git_directory_gently(&nongit);
|
||||||
if (!nongit) {
|
|
||||||
int count;
|
|
||||||
const char** new_argv;
|
|
||||||
|
|
||||||
alias_command = (*argv)[0];
|
alias_command = (*argv)[0];
|
||||||
git_config(git_alias_config);
|
git_config(git_alias_config);
|
||||||
if (alias_string) {
|
if (alias_string) {
|
||||||
|
|
||||||
count = split_cmdline(alias_string, &new_argv);
|
count = split_cmdline(alias_string, &new_argv);
|
||||||
|
option_count = handle_options(&new_argv, &count);
|
||||||
|
memmove(new_argv - option_count, new_argv,
|
||||||
|
count * sizeof(char *));
|
||||||
|
new_argv -= option_count;
|
||||||
|
|
||||||
if (count < 1)
|
if (count < 1)
|
||||||
die("empty alias for %s", alias_command);
|
die("empty alias for %s", alias_command);
|
||||||
@ -133,20 +188,17 @@ static int handle_alias(int *argcp, const char ***argv)
|
|||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* insert after command name */
|
|
||||||
if (*argcp > 1) {
|
|
||||||
new_argv = realloc(new_argv, sizeof(char*) *
|
new_argv = realloc(new_argv, sizeof(char*) *
|
||||||
(count + *argcp));
|
(count + *argcp + 1));
|
||||||
memcpy(new_argv + count, *argv + 1,
|
/* insert after command name */
|
||||||
sizeof(char*) * *argcp);
|
memcpy(new_argv + count, *argv + 1, sizeof(char*) * *argcp);
|
||||||
}
|
new_argv[count+*argcp] = NULL;
|
||||||
|
|
||||||
*argv = new_argv;
|
*argv = new_argv;
|
||||||
*argcp += count - 1;
|
*argcp += count - 1;
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (subdir)
|
if (subdir)
|
||||||
chdir(subdir);
|
chdir(subdir);
|
||||||
@ -158,51 +210,55 @@ static int handle_alias(int *argcp, const char ***argv)
|
|||||||
|
|
||||||
const char git_version_string[] = GIT_VERSION;
|
const char git_version_string[] = GIT_VERSION;
|
||||||
|
|
||||||
|
#define NEEDS_PREFIX 1
|
||||||
|
|
||||||
static void handle_internal_command(int argc, const char **argv, char **envp)
|
static void handle_internal_command(int argc, const char **argv, char **envp)
|
||||||
{
|
{
|
||||||
const char *cmd = argv[0];
|
const char *cmd = argv[0];
|
||||||
static struct cmd_struct {
|
static struct cmd_struct {
|
||||||
const char *cmd;
|
const char *cmd;
|
||||||
int (*fn)(int, const char **, char **);
|
int (*fn)(int, const char **, const char *);
|
||||||
|
int prefix;
|
||||||
} commands[] = {
|
} commands[] = {
|
||||||
{ "version", cmd_version },
|
{ "version", cmd_version },
|
||||||
{ "help", cmd_help },
|
{ "help", cmd_help },
|
||||||
{ "log", cmd_log },
|
{ "log", cmd_log, NEEDS_PREFIX },
|
||||||
{ "whatchanged", cmd_whatchanged },
|
{ "whatchanged", cmd_whatchanged, NEEDS_PREFIX },
|
||||||
{ "show", cmd_show },
|
{ "show", cmd_show, NEEDS_PREFIX },
|
||||||
{ "push", cmd_push },
|
{ "push", cmd_push },
|
||||||
{ "format-patch", cmd_format_patch },
|
{ "format-patch", cmd_format_patch, NEEDS_PREFIX },
|
||||||
{ "count-objects", cmd_count_objects },
|
{ "count-objects", cmd_count_objects },
|
||||||
{ "diff", cmd_diff },
|
{ "diff", cmd_diff, NEEDS_PREFIX },
|
||||||
{ "grep", cmd_grep },
|
{ "grep", cmd_grep, NEEDS_PREFIX },
|
||||||
{ "rm", cmd_rm },
|
{ "rm", cmd_rm, NEEDS_PREFIX },
|
||||||
{ "add", cmd_add },
|
{ "add", cmd_add, NEEDS_PREFIX },
|
||||||
{ "rev-list", cmd_rev_list },
|
{ "rev-list", cmd_rev_list, NEEDS_PREFIX },
|
||||||
{ "init-db", cmd_init_db },
|
{ "init-db", cmd_init_db },
|
||||||
{ "get-tar-commit-id", cmd_get_tar_commit_id },
|
{ "get-tar-commit-id", cmd_get_tar_commit_id },
|
||||||
{ "upload-tar", cmd_upload_tar },
|
{ "upload-tar", cmd_upload_tar },
|
||||||
{ "check-ref-format", cmd_check_ref_format },
|
{ "check-ref-format", cmd_check_ref_format },
|
||||||
{ "ls-files", cmd_ls_files },
|
{ "ls-files", cmd_ls_files, NEEDS_PREFIX },
|
||||||
{ "ls-tree", cmd_ls_tree },
|
{ "ls-tree", cmd_ls_tree, NEEDS_PREFIX },
|
||||||
{ "tar-tree", cmd_tar_tree },
|
{ "tar-tree", cmd_tar_tree, NEEDS_PREFIX },
|
||||||
{ "read-tree", cmd_read_tree },
|
{ "read-tree", cmd_read_tree, NEEDS_PREFIX },
|
||||||
{ "commit-tree", cmd_commit_tree },
|
{ "commit-tree", cmd_commit_tree, NEEDS_PREFIX },
|
||||||
{ "apply", cmd_apply },
|
{ "apply", cmd_apply },
|
||||||
{ "show-branch", cmd_show_branch },
|
{ "show-branch", cmd_show_branch, NEEDS_PREFIX },
|
||||||
{ "diff-files", cmd_diff_files },
|
{ "diff-files", cmd_diff_files, NEEDS_PREFIX },
|
||||||
{ "diff-index", cmd_diff_index },
|
{ "diff-index", cmd_diff_index, NEEDS_PREFIX },
|
||||||
{ "diff-stages", cmd_diff_stages },
|
{ "diff-stages", cmd_diff_stages, NEEDS_PREFIX },
|
||||||
{ "diff-tree", cmd_diff_tree },
|
{ "diff-tree", cmd_diff_tree, NEEDS_PREFIX },
|
||||||
{ "cat-file", cmd_cat_file },
|
{ "cat-file", cmd_cat_file, NEEDS_PREFIX },
|
||||||
{ "rev-parse", cmd_rev_parse },
|
{ "rev-parse", cmd_rev_parse, NEEDS_PREFIX },
|
||||||
{ "write-tree", cmd_write_tree },
|
{ "write-tree", cmd_write_tree, NEEDS_PREFIX },
|
||||||
{ "mailsplit", cmd_mailsplit },
|
{ "mailsplit", cmd_mailsplit },
|
||||||
{ "mailinfo", cmd_mailinfo },
|
{ "mailinfo", cmd_mailinfo },
|
||||||
{ "stripspace", cmd_stripspace },
|
{ "stripspace", cmd_stripspace },
|
||||||
{ "update-index", cmd_update_index },
|
{ "update-index", cmd_update_index, NEEDS_PREFIX },
|
||||||
{ "update-ref", cmd_update_ref },
|
{ "update-ref", cmd_update_ref, NEEDS_PREFIX },
|
||||||
{ "fmt-merge-msg", cmd_fmt_merge_msg },
|
{ "fmt-merge-msg", cmd_fmt_merge_msg, NEEDS_PREFIX },
|
||||||
{ "prune", cmd_prune },
|
{ "prune", cmd_prune, NEEDS_PREFIX },
|
||||||
|
{ "mv", cmd_mv, NEEDS_PREFIX },
|
||||||
};
|
};
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -214,9 +270,13 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
|
|||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(commands); i++) {
|
for (i = 0; i < ARRAY_SIZE(commands); i++) {
|
||||||
struct cmd_struct *p = commands+i;
|
struct cmd_struct *p = commands+i;
|
||||||
|
const char *prefix;
|
||||||
if (strcmp(p->cmd, cmd))
|
if (strcmp(p->cmd, cmd))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
prefix = NULL;
|
||||||
|
if (p->prefix)
|
||||||
|
prefix = setup_git_directory();
|
||||||
if (getenv("GIT_TRACE")) {
|
if (getenv("GIT_TRACE")) {
|
||||||
int i;
|
int i;
|
||||||
fprintf(stderr, "trace: built-in: git");
|
fprintf(stderr, "trace: built-in: git");
|
||||||
@ -228,7 +288,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
|
|||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
exit(p->fn(argc, argv, envp));
|
exit(p->fn(argc, argv, prefix));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,51 +329,19 @@ int main(int argc, const char **argv, char **envp)
|
|||||||
die("cannot handle %s internally", cmd);
|
die("cannot handle %s internally", cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Default command: "help" */
|
|
||||||
cmd = "help";
|
|
||||||
|
|
||||||
/* Look for flags.. */
|
/* Look for flags.. */
|
||||||
while (argc > 1) {
|
argv++;
|
||||||
cmd = *++argv;
|
|
||||||
argc--;
|
argc--;
|
||||||
|
handle_options(&argv, &argc);
|
||||||
if (!strcmp(cmd, "-p") || !strcmp(cmd, "--paginate")) {
|
if (argc > 0) {
|
||||||
setup_pager();
|
if (!strncmp(argv[0], "--", 2))
|
||||||
continue;
|
argv[0] += 2;
|
||||||
|
} else {
|
||||||
|
/* Default command: "help" */
|
||||||
|
argv[0] = "help";
|
||||||
|
argc = 1;
|
||||||
}
|
}
|
||||||
|
cmd = argv[0];
|
||||||
if (strncmp(cmd, "--", 2))
|
|
||||||
break;
|
|
||||||
|
|
||||||
cmd += 2;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For legacy reasons, the "version" and "help"
|
|
||||||
* commands can be written with "--" prepended
|
|
||||||
* to make them look like flags.
|
|
||||||
*/
|
|
||||||
if (!strcmp(cmd, "help"))
|
|
||||||
break;
|
|
||||||
if (!strcmp(cmd, "version"))
|
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check remaining flags (which by now must be
|
|
||||||
* "--exec-path", but maybe we will accept
|
|
||||||
* other arguments some day)
|
|
||||||
*/
|
|
||||||
if (!strncmp(cmd, "exec-path", 9)) {
|
|
||||||
cmd += 9;
|
|
||||||
if (*cmd == '=') {
|
|
||||||
git_set_exec_path(cmd + 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
puts(git_exec_path());
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
cmd_usage(0, NULL, NULL);
|
|
||||||
}
|
|
||||||
argv[0] = cmd;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We search for git commands in the following order:
|
* We search for git commands in the following order:
|
||||||
|
@ -227,7 +227,7 @@ if (!defined $action || $action eq "summary") {
|
|||||||
git_tag();
|
git_tag();
|
||||||
exit;
|
exit;
|
||||||
} elsif ($action eq "blame") {
|
} elsif ($action eq "blame") {
|
||||||
git_blame();
|
git_blame2();
|
||||||
exit;
|
exit;
|
||||||
} else {
|
} else {
|
||||||
undef $action;
|
undef $action;
|
||||||
@ -795,7 +795,7 @@ sub git_read_projects {
|
|||||||
if (-d $projects_list) {
|
if (-d $projects_list) {
|
||||||
# search in directory
|
# search in directory
|
||||||
my $dir = $projects_list;
|
my $dir = $projects_list;
|
||||||
opendir my $dh, $dir or return undef;
|
opendir my ($dh), $dir or return undef;
|
||||||
while (my $dir = readdir($dh)) {
|
while (my $dir = readdir($dh)) {
|
||||||
if (-e "$projectroot/$dir/HEAD") {
|
if (-e "$projectroot/$dir/HEAD") {
|
||||||
my $pr = {
|
my $pr = {
|
||||||
@ -810,7 +810,7 @@ sub git_read_projects {
|
|||||||
# 'git%2Fgit.git Linus+Torvalds'
|
# 'git%2Fgit.git Linus+Torvalds'
|
||||||
# 'libs%2Fklibc%2Fklibc.git H.+Peter+Anvin'
|
# 'libs%2Fklibc%2Fklibc.git H.+Peter+Anvin'
|
||||||
# 'linux%2Fhotplug%2Fudev.git Greg+Kroah-Hartman'
|
# 'linux%2Fhotplug%2Fudev.git Greg+Kroah-Hartman'
|
||||||
open my $fd , $projects_list or return undef;
|
open my ($fd), $projects_list or return undef;
|
||||||
while (my $line = <$fd>) {
|
while (my $line = <$fd>) {
|
||||||
chomp $line;
|
chomp $line;
|
||||||
my ($path, $owner) = split ' ', $line;
|
my ($path, $owner) = split ' ', $line;
|
||||||
@ -1138,7 +1138,7 @@ sub git_summary {
|
|||||||
"</td>\n" .
|
"</td>\n" .
|
||||||
"<td>";
|
"<td>";
|
||||||
if (defined($comment)) {
|
if (defined($comment)) {
|
||||||
print $cgi->a({-class => "list", -href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}")}, $comment);
|
print $cgi->a({-class => "list", -href => "$my_uri?" . esc_param("p=$project;a=tag;h=$tag{'id'}")}, esc_html($comment));
|
||||||
}
|
}
|
||||||
print "</td>\n" .
|
print "</td>\n" .
|
||||||
"<td class=\"link\">";
|
"<td class=\"link\">";
|
||||||
@ -1199,6 +1199,20 @@ sub git_summary {
|
|||||||
git_footer_html();
|
git_footer_html();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub git_print_page_path {
|
||||||
|
my $name = shift;
|
||||||
|
my $type = shift;
|
||||||
|
|
||||||
|
if (!defined $name) {
|
||||||
|
print "<div class=\"page_path\"><b>/</b></div>\n";
|
||||||
|
} elsif ($type =~ "blob") {
|
||||||
|
print "<div class=\"page_path\"><b>" .
|
||||||
|
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;f=$file_name")}, esc_html($name)) . "</b><br/></div>\n";
|
||||||
|
} else {
|
||||||
|
print "<div class=\"page_path\"><b>" . esc_html($name) . "</b><br/></div>\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sub git_tag {
|
sub git_tag {
|
||||||
my $head = git_read_head($project);
|
my $head = git_read_head($project);
|
||||||
git_header_html();
|
git_header_html();
|
||||||
@ -1238,6 +1252,73 @@ sub git_tag {
|
|||||||
git_footer_html();
|
git_footer_html();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub git_blame2 {
|
||||||
|
my $fd;
|
||||||
|
my $ftype;
|
||||||
|
die_error(undef, "Permission denied.") if (!git_get_project_config_bool ('blame'));
|
||||||
|
die_error('404 Not Found', "File name not defined") if (!$file_name);
|
||||||
|
$hash_base ||= git_read_head($project);
|
||||||
|
die_error(undef, "Reading commit failed") unless ($hash_base);
|
||||||
|
my %co = git_read_commit($hash_base)
|
||||||
|
or die_error(undef, "Reading commit failed");
|
||||||
|
if (!defined $hash) {
|
||||||
|
$hash = git_get_hash_by_path($hash_base, $file_name, "blob")
|
||||||
|
or die_error(undef, "Error looking up file");
|
||||||
|
}
|
||||||
|
$ftype = git_get_type($hash);
|
||||||
|
if ($ftype !~ "blob") {
|
||||||
|
die_error("400 Bad Request", "object is not a blob");
|
||||||
|
}
|
||||||
|
open ($fd, "-|", $GIT, "blame", '-l', $file_name, $hash_base)
|
||||||
|
or die_error(undef, "Open failed");
|
||||||
|
git_header_html();
|
||||||
|
print "<div class=\"page_nav\">\n" .
|
||||||
|
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, "summary") .
|
||||||
|
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "shortlog") .
|
||||||
|
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log")}, "log") .
|
||||||
|
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base")}, "commit") .
|
||||||
|
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash_base")}, "commitdiff") .
|
||||||
|
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash_base")}, "tree") . "<br/>\n";
|
||||||
|
print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$hash;hb=$hash_base;f=$file_name")}, "blob") .
|
||||||
|
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;f=$file_name")}, "head") . "<br/>\n";
|
||||||
|
print "</div>\n".
|
||||||
|
"<div>" .
|
||||||
|
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'})) .
|
||||||
|
"</div>\n";
|
||||||
|
git_print_page_path($file_name, $ftype);
|
||||||
|
my @rev_color = (qw(light dark));
|
||||||
|
my $num_colors = scalar(@rev_color);
|
||||||
|
my $current_color = 0;
|
||||||
|
my $last_rev;
|
||||||
|
print "<div class=\"page_body\">\n";
|
||||||
|
print "<table class=\"blame\">\n";
|
||||||
|
print "<tr><th>Commit</th><th>Line</th><th>Data</th></tr>\n";
|
||||||
|
while (<$fd>) {
|
||||||
|
/^([0-9a-fA-F]{40}).*?(\d+)\)\s{1}(\s*.*)/;
|
||||||
|
my $full_rev = $1;
|
||||||
|
my $rev = substr($full_rev, 0, 8);
|
||||||
|
my $lineno = $2;
|
||||||
|
my $data = $3;
|
||||||
|
|
||||||
|
if (!defined $last_rev) {
|
||||||
|
$last_rev = $full_rev;
|
||||||
|
} elsif ($last_rev ne $full_rev) {
|
||||||
|
$last_rev = $full_rev;
|
||||||
|
$current_color = ++$current_color % $num_colors;
|
||||||
|
}
|
||||||
|
print "<tr class=\"$rev_color[$current_color]\">\n";
|
||||||
|
print "<td class=\"sha1\">" .
|
||||||
|
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$full_rev;f=$file_name")}, esc_html($rev)) . "</td>\n";
|
||||||
|
print "<td class=\"linenr\"><a id=\"l$lineno\" href=\"#l$lineno\" class=\"linenr\">" . esc_html($lineno) . "</a></td>\n";
|
||||||
|
print "<td class=\"pre\">" . esc_html($data) . "</td>\n";
|
||||||
|
print "</tr>\n";
|
||||||
|
}
|
||||||
|
print "</table>\n";
|
||||||
|
print "</div>";
|
||||||
|
close $fd or print "Reading blob failed\n";
|
||||||
|
git_footer_html();
|
||||||
|
}
|
||||||
|
|
||||||
sub git_blame {
|
sub git_blame {
|
||||||
my $fd;
|
my $fd;
|
||||||
die_error('403 Permission denied', "Permission denied.") if (!git_get_project_config_bool ('blame'));
|
die_error('403 Permission denied', "Permission denied.") if (!git_get_project_config_bool ('blame'));
|
||||||
@ -1266,7 +1347,7 @@ sub git_blame {
|
|||||||
"<div>" .
|
"<div>" .
|
||||||
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'})) .
|
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'})) .
|
||||||
"</div>\n";
|
"</div>\n";
|
||||||
print "<div class=\"page_path\"><b>" . esc_html($file_name) . "</b></div>\n";
|
git_print_page_path($file_name);
|
||||||
print "<div class=\"page_body\">\n";
|
print "<div class=\"page_body\">\n";
|
||||||
print <<HTML;
|
print <<HTML;
|
||||||
<table class="blame">
|
<table class="blame">
|
||||||
@ -1531,6 +1612,14 @@ sub git_blob_plain_mimetype {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub git_blob_plain {
|
sub git_blob_plain {
|
||||||
|
if (!defined $hash) {
|
||||||
|
if (defined $file_name) {
|
||||||
|
my $base = $hash_base || git_read_head($project);
|
||||||
|
$hash = git_get_hash_by_path($base, $file_name, "blob") || die_error(undef, "Error lookup file.");
|
||||||
|
} else {
|
||||||
|
die_error(undef, "No file name defined.");
|
||||||
|
}
|
||||||
|
}
|
||||||
my $type = shift;
|
my $type = shift;
|
||||||
open my $fd, "-|", "$GIT cat-file blob $hash" or die_error("Couldn't cat $file_name, $hash");
|
open my $fd, "-|", "$GIT cat-file blob $hash" or die_error("Couldn't cat $file_name, $hash");
|
||||||
|
|
||||||
@ -1554,9 +1643,13 @@ sub git_blob_plain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub git_blob {
|
sub git_blob {
|
||||||
if (!defined $hash && defined $file_name) {
|
if (!defined $hash) {
|
||||||
|
if (defined $file_name) {
|
||||||
my $base = $hash_base || git_read_head($project);
|
my $base = $hash_base || git_read_head($project);
|
||||||
$hash = git_get_hash_by_path($base, $file_name, "blob") || die_error(undef, "Error lookup file.");
|
$hash = git_get_hash_by_path($base, $file_name, "blob") || die_error(undef, "Error lookup file.");
|
||||||
|
} else {
|
||||||
|
die_error(undef, "No file name defined.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
my $have_blame = git_get_project_config_bool ('blame');
|
my $have_blame = git_get_project_config_bool ('blame');
|
||||||
open my $fd, "-|", "$GIT cat-file blob $hash" or die_error(undef, "Open failed.");
|
open my $fd, "-|", "$GIT cat-file blob $hash" or die_error(undef, "Open failed.");
|
||||||
@ -1592,9 +1685,7 @@ sub git_blob {
|
|||||||
"<br/><br/></div>\n" .
|
"<br/><br/></div>\n" .
|
||||||
"<div class=\"title\">$hash</div>\n";
|
"<div class=\"title\">$hash</div>\n";
|
||||||
}
|
}
|
||||||
if (defined $file_name) {
|
git_print_page_path($file_name, "blob");
|
||||||
print "<div class=\"page_path\"><b>" . esc_html($file_name) . "</b></div>\n";
|
|
||||||
}
|
|
||||||
print "<div class=\"page_body\">\n";
|
print "<div class=\"page_body\">\n";
|
||||||
my $nr;
|
my $nr;
|
||||||
while (my $line = <$fd>) {
|
while (my $line = <$fd>) {
|
||||||
@ -1659,10 +1750,8 @@ sub git_tree {
|
|||||||
}
|
}
|
||||||
if (defined $file_name) {
|
if (defined $file_name) {
|
||||||
$base = esc_html("$file_name/");
|
$base = esc_html("$file_name/");
|
||||||
print "<div class=\"page_path\"><b>/" . esc_html($file_name) . "</b></div>\n";
|
|
||||||
} else {
|
|
||||||
print "<div class=\"page_path\"><b>/</b></div>\n";
|
|
||||||
}
|
}
|
||||||
|
git_print_page_path($file_name);
|
||||||
print "<div class=\"page_body\">\n";
|
print "<div class=\"page_body\">\n";
|
||||||
print "<table cellspacing=\"0\">\n";
|
print "<table cellspacing=\"0\">\n";
|
||||||
my $alternate = 0;
|
my $alternate = 0;
|
||||||
@ -1687,7 +1776,7 @@ sub git_tree {
|
|||||||
"<td class=\"link\">" .
|
"<td class=\"link\">" .
|
||||||
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$t_hash$base_key;f=$base$t_name")}, "blob") .
|
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$t_hash$base_key;f=$base$t_name")}, "blob") .
|
||||||
# " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;h=$t_hash$base_key;f=$base$t_name")}, "blame") .
|
# " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;h=$t_hash$base_key;f=$base$t_name")}, "blame") .
|
||||||
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;h=$hash_base;f=$base$t_name")}, "history") .
|
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;h=$t_hash;hb=$hash_base;f=$base$t_name")}, "history") .
|
||||||
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$t_hash;f=$base$t_name")}, "raw") .
|
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$t_hash;f=$base$t_name")}, "raw") .
|
||||||
"</td>\n";
|
"</td>\n";
|
||||||
} elsif ($t_type eq "tree") {
|
} elsif ($t_type eq "tree") {
|
||||||
@ -1696,7 +1785,7 @@ sub git_tree {
|
|||||||
"</td>\n" .
|
"</td>\n" .
|
||||||
"<td class=\"link\">" .
|
"<td class=\"link\">" .
|
||||||
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$t_hash$base_key;f=$base$t_name")}, "tree") .
|
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$t_hash$base_key;f=$base$t_name")}, "tree") .
|
||||||
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;h=$hash_base;f=$base$t_name")}, "history") .
|
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;hb=$hash_base;f=$base$t_name")}, "history") .
|
||||||
"</td>\n";
|
"</td>\n";
|
||||||
}
|
}
|
||||||
print "</tr>\n";
|
print "</tr>\n";
|
||||||
@ -1931,7 +2020,13 @@ sub git_commit {
|
|||||||
print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash")}, "commitdiff");
|
print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash")}, "commitdiff");
|
||||||
}
|
}
|
||||||
print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash")}, "tree") . "\n" .
|
print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash")}, "tree") . "\n" .
|
||||||
"<br/><br/></div>\n";
|
"<br/>\n";
|
||||||
|
if (defined $file_name && defined $co{'parent'}) {
|
||||||
|
my $parent = $co{'parent'};
|
||||||
|
print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;hb=$parent;f=$file_name")}, "blame") . "\n";
|
||||||
|
}
|
||||||
|
print "<br/></div>\n";
|
||||||
|
|
||||||
if (defined $co{'parent'}) {
|
if (defined $co{'parent'}) {
|
||||||
print "<div>\n" .
|
print "<div>\n" .
|
||||||
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash"), -class => "title"}, esc_html($co{'title'}) . $ref) . "\n" .
|
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash"), -class => "title"}, esc_html($co{'title'}) . $ref) . "\n" .
|
||||||
@ -2041,7 +2136,7 @@ sub git_commit {
|
|||||||
"<td><span class=\"file_status deleted\">[deleted " . file_type($from_mode). "]</span></td>\n" .
|
"<td><span class=\"file_status deleted\">[deleted " . file_type($from_mode). "]</span></td>\n" .
|
||||||
"<td class=\"link\">" .
|
"<td class=\"link\">" .
|
||||||
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$hash;f=$file")}, "blob") .
|
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$hash;f=$file")}, "blob") .
|
||||||
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;h=$hash;f=$file")}, "history") .
|
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;hb=$hash;f=$file")}, "history") .
|
||||||
"</td>\n"
|
"</td>\n"
|
||||||
} elsif ($status eq "M" || $status eq "T") {
|
} elsif ($status eq "M" || $status eq "T") {
|
||||||
my $mode_chnge = "";
|
my $mode_chnge = "";
|
||||||
@ -2072,7 +2167,7 @@ sub git_commit {
|
|||||||
if ($to_id ne $from_id) {
|
if ($to_id ne $from_id) {
|
||||||
print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$file")}, "diff");
|
print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$file")}, "diff");
|
||||||
}
|
}
|
||||||
print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;h=$hash;f=$file")}, "history") . "\n";
|
print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;hb=$hash;f=$file")}, "history") . "\n";
|
||||||
print "</td>\n";
|
print "</td>\n";
|
||||||
} elsif ($status eq "R") {
|
} elsif ($status eq "R") {
|
||||||
my ($from_file, $to_file) = split "\t", $file;
|
my ($from_file, $to_file) = split "\t", $file;
|
||||||
@ -2120,9 +2215,7 @@ sub git_blobdiff {
|
|||||||
"<br/><br/></div>\n" .
|
"<br/><br/></div>\n" .
|
||||||
"<div class=\"title\">$hash vs $hash_parent</div>\n";
|
"<div class=\"title\">$hash vs $hash_parent</div>\n";
|
||||||
}
|
}
|
||||||
if (defined $file_name) {
|
git_print_page_path($file_name, "blob");
|
||||||
print "<div class=\"page_path\"><b>/" . esc_html($file_name) . "</b></div>\n";
|
|
||||||
}
|
|
||||||
print "<div class=\"page_body\">\n" .
|
print "<div class=\"page_body\">\n" .
|
||||||
"<div class=\"diff_info\">blob:" .
|
"<div class=\"diff_info\">blob:" .
|
||||||
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$hash_parent;hb=$hash_base;f=$file_name")}, $hash_parent) .
|
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$hash_parent;hb=$hash_base;f=$file_name")}, $hash_parent) .
|
||||||
@ -2293,10 +2386,11 @@ sub git_commitdiff_plain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub git_history {
|
sub git_history {
|
||||||
if (!defined $hash) {
|
if (!defined $hash_base) {
|
||||||
$hash = git_read_head($project);
|
$hash_base = git_read_head($project);
|
||||||
}
|
}
|
||||||
my %co = git_read_commit($hash);
|
my $ftype;
|
||||||
|
my %co = git_read_commit($hash_base);
|
||||||
if (!%co) {
|
if (!%co) {
|
||||||
die_error(undef, "Unknown commit object.");
|
die_error(undef, "Unknown commit object.");
|
||||||
}
|
}
|
||||||
@ -2306,18 +2400,24 @@ sub git_history {
|
|||||||
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, "summary") .
|
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, "summary") .
|
||||||
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "shortlog") .
|
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "shortlog") .
|
||||||
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log")}, "log") .
|
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log")}, "log") .
|
||||||
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash")}, "commit") .
|
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base")}, "commit") .
|
||||||
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash")}, "commitdiff") .
|
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash_base")}, "commitdiff") .
|
||||||
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash")}, "tree") .
|
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash_base")}, "tree") .
|
||||||
"<br/><br/>\n" .
|
"<br/><br/>\n" .
|
||||||
"</div>\n";
|
"</div>\n";
|
||||||
print "<div>\n" .
|
print "<div>\n" .
|
||||||
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash"), -class => "title"}, esc_html($co{'title'})) . "\n" .
|
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'})) . "\n" .
|
||||||
"</div>\n";
|
"</div>\n";
|
||||||
print "<div class=\"page_path\"><b>/" . esc_html($file_name) . "</b><br/></div>\n";
|
if (!defined $hash && defined $file_name) {
|
||||||
|
$hash = git_get_hash_by_path($hash_base, $file_name);
|
||||||
|
}
|
||||||
|
if (defined $hash) {
|
||||||
|
$ftype = git_get_type($hash);
|
||||||
|
}
|
||||||
|
git_print_page_path($file_name, $ftype);
|
||||||
|
|
||||||
open my $fd, "-|",
|
open my $fd, "-|",
|
||||||
"$GIT rev-list --full-history $hash -- \'$file_name\'";
|
"$GIT rev-list --full-history $hash_base -- \'$file_name\'";
|
||||||
print "<table cellspacing=\"0\">\n";
|
print "<table cellspacing=\"0\">\n";
|
||||||
my $alternate = 0;
|
my $alternate = 0;
|
||||||
while (my $line = <$fd>) {
|
while (my $line = <$fd>) {
|
||||||
@ -2345,7 +2445,7 @@ sub git_history {
|
|||||||
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit")}, "commit") .
|
$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit")}, "commit") .
|
||||||
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$commit")}, "commitdiff") .
|
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$commit")}, "commitdiff") .
|
||||||
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;hb=$commit;f=$file_name")}, "blob");
|
" | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;hb=$commit;f=$file_name")}, "blob");
|
||||||
my $blob = git_get_hash_by_path($hash, $file_name);
|
my $blob = git_get_hash_by_path($hash_base, $file_name);
|
||||||
my $blob_parent = git_get_hash_by_path($commit, $file_name);
|
my $blob_parent = git_get_hash_by_path($commit, $file_name);
|
||||||
if (defined $blob && defined $blob_parent && $blob ne $blob_parent) {
|
if (defined $blob && defined $blob_parent && $blob ne $blob_parent) {
|
||||||
print " | " .
|
print " | " .
|
||||||
|
45
http-fetch.c
45
http-fetch.c
@ -36,6 +36,8 @@ enum XML_Status {
|
|||||||
#define PREV_BUF_SIZE 4096
|
#define PREV_BUF_SIZE 4096
|
||||||
#define RANGE_HEADER_SIZE 30
|
#define RANGE_HEADER_SIZE 30
|
||||||
|
|
||||||
|
static int commits_on_stdin = 0;
|
||||||
|
|
||||||
static int got_alternates = -1;
|
static int got_alternates = -1;
|
||||||
static int corrupt_object_found = 0;
|
static int corrupt_object_found = 0;
|
||||||
|
|
||||||
@ -43,7 +45,7 @@ static struct curl_slist *no_pragma_header;
|
|||||||
|
|
||||||
struct alt_base
|
struct alt_base
|
||||||
{
|
{
|
||||||
char *base;
|
const char *base;
|
||||||
int path_len;
|
int path_len;
|
||||||
int got_indices;
|
int got_indices;
|
||||||
struct packed_git *packs;
|
struct packed_git *packs;
|
||||||
@ -81,7 +83,7 @@ struct object_request
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct alternates_request {
|
struct alternates_request {
|
||||||
char *base;
|
const char *base;
|
||||||
char *url;
|
char *url;
|
||||||
struct buffer *buffer;
|
struct buffer *buffer;
|
||||||
struct active_request_slot *slot;
|
struct active_request_slot *slot;
|
||||||
@ -142,7 +144,7 @@ static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb,
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fetch_alternates(char *base);
|
static void fetch_alternates(const char *base);
|
||||||
|
|
||||||
static void process_object_response(void *callback_data);
|
static void process_object_response(void *callback_data);
|
||||||
|
|
||||||
@ -507,7 +509,7 @@ static void process_alternates_response(void *callback_data)
|
|||||||
(struct alternates_request *)callback_data;
|
(struct alternates_request *)callback_data;
|
||||||
struct active_request_slot *slot = alt_req->slot;
|
struct active_request_slot *slot = alt_req->slot;
|
||||||
struct alt_base *tail = alt;
|
struct alt_base *tail = alt;
|
||||||
char *base = alt_req->base;
|
const char *base = alt_req->base;
|
||||||
static const char null_byte = '\0';
|
static const char null_byte = '\0';
|
||||||
char *data;
|
char *data;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -612,7 +614,7 @@ static void process_alternates_response(void *callback_data)
|
|||||||
got_alternates = 1;
|
got_alternates = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fetch_alternates(char *base)
|
static void fetch_alternates(const char *base)
|
||||||
{
|
{
|
||||||
struct buffer buffer;
|
struct buffer buffer;
|
||||||
char *url;
|
char *url;
|
||||||
@ -1185,7 +1187,7 @@ int fetch_ref(char *ref, unsigned char *sha1)
|
|||||||
char *url;
|
char *url;
|
||||||
char hex[42];
|
char hex[42];
|
||||||
struct buffer buffer;
|
struct buffer buffer;
|
||||||
char *base = alt->base;
|
const char *base = alt->base;
|
||||||
struct active_request_slot *slot;
|
struct active_request_slot *slot;
|
||||||
struct slot_results results;
|
struct slot_results results;
|
||||||
buffer.size = 41;
|
buffer.size = 41;
|
||||||
@ -1214,10 +1216,12 @@ int fetch_ref(char *ref, unsigned char *sha1)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
char *commit_id;
|
int commits;
|
||||||
char *url;
|
const char **write_ref = NULL;
|
||||||
|
char **commit_id;
|
||||||
|
const char *url;
|
||||||
char *path;
|
char *path;
|
||||||
int arg = 1;
|
int arg = 1;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@ -1237,20 +1241,26 @@ int main(int argc, char **argv)
|
|||||||
} else if (argv[arg][1] == 'v') {
|
} else if (argv[arg][1] == 'v') {
|
||||||
get_verbosely = 1;
|
get_verbosely = 1;
|
||||||
} else if (argv[arg][1] == 'w') {
|
} else if (argv[arg][1] == 'w') {
|
||||||
write_ref = argv[arg + 1];
|
write_ref = &argv[arg + 1];
|
||||||
arg++;
|
arg++;
|
||||||
} else if (!strcmp(argv[arg], "--recover")) {
|
} else if (!strcmp(argv[arg], "--recover")) {
|
||||||
get_recover = 1;
|
get_recover = 1;
|
||||||
|
} else if (!strcmp(argv[arg], "--stdin")) {
|
||||||
|
commits_on_stdin = 1;
|
||||||
}
|
}
|
||||||
arg++;
|
arg++;
|
||||||
}
|
}
|
||||||
if (argc < arg + 2) {
|
if (argc < arg + 2 - commits_on_stdin) {
|
||||||
usage("git-http-fetch [-c] [-t] [-a] [-d] [-v] [--recover] [-w ref] commit-id url");
|
usage("git-http-fetch [-c] [-t] [-a] [-v] [--recover] [-w ref] [--stdin] commit-id url");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
commit_id = argv[arg];
|
if (commits_on_stdin) {
|
||||||
url = argv[arg + 1];
|
commits = pull_targets_stdin(&commit_id, &write_ref);
|
||||||
write_ref_log_details = url;
|
} else {
|
||||||
|
commit_id = (char **) &argv[arg++];
|
||||||
|
commits = 1;
|
||||||
|
}
|
||||||
|
url = argv[arg];
|
||||||
|
|
||||||
http_init();
|
http_init();
|
||||||
|
|
||||||
@ -1268,13 +1278,16 @@ int main(int argc, char **argv)
|
|||||||
alt->path_len = strlen(path);
|
alt->path_len = strlen(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pull(commit_id))
|
if (pull(commits, commit_id, write_ref, url))
|
||||||
rc = 1;
|
rc = 1;
|
||||||
|
|
||||||
http_cleanup();
|
http_cleanup();
|
||||||
|
|
||||||
curl_slist_free_all(no_pragma_header);
|
curl_slist_free_all(no_pragma_header);
|
||||||
|
|
||||||
|
if (commits_on_stdin)
|
||||||
|
pull_targets_free(commits, commit_id, write_ref);
|
||||||
|
|
||||||
if (corrupt_object_found) {
|
if (corrupt_object_found) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Some loose object were found to be corrupt, but they might be just\n"
|
"Some loose object were found to be corrupt, but they might be just\n"
|
||||||
|
@ -2521,7 +2521,7 @@ int main(int argc, char **argv)
|
|||||||
commit_argv[3] = old_sha1_hex;
|
commit_argv[3] = old_sha1_hex;
|
||||||
commit_argc++;
|
commit_argc++;
|
||||||
}
|
}
|
||||||
init_revisions(&revs);
|
init_revisions(&revs, setup_git_directory());
|
||||||
setup_revisions(commit_argc, commit_argv, &revs, NULL);
|
setup_revisions(commit_argc, commit_argv, &revs, NULL);
|
||||||
free(new_sha1_hex);
|
free(new_sha1_hex);
|
||||||
if (old_sha1_hex) {
|
if (old_sha1_hex) {
|
||||||
|
@ -8,8 +8,9 @@
|
|||||||
static int use_link = 0;
|
static int use_link = 0;
|
||||||
static int use_symlink = 0;
|
static int use_symlink = 0;
|
||||||
static int use_filecopy = 1;
|
static int use_filecopy = 1;
|
||||||
|
static int commits_on_stdin = 0;
|
||||||
|
|
||||||
static char *path; /* "Remote" git repository */
|
static const char *path; /* "Remote" git repository */
|
||||||
|
|
||||||
void prefetch(unsigned char *sha1)
|
void prefetch(unsigned char *sha1)
|
||||||
{
|
{
|
||||||
@ -194,7 +195,7 @@ int fetch_ref(char *ref, unsigned char *sha1)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const char local_pull_usage[] =
|
static const char local_pull_usage[] =
|
||||||
"git-local-fetch [-c] [-t] [-a] [-d] [-v] [-w filename] [--recover] [-l] [-s] [-n] commit-id path";
|
"git-local-fetch [-c] [-t] [-a] [-v] [-w filename] [--recover] [-l] [-s] [-n] [--stdin] commit-id path";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* By default we only use file copy.
|
* By default we only use file copy.
|
||||||
@ -202,9 +203,11 @@ static const char local_pull_usage[] =
|
|||||||
* If -s is specified, then a symlink is attempted.
|
* If -s is specified, then a symlink is attempted.
|
||||||
* If -n is _not_ specified, then a regular file-to-file copy is done.
|
* If -n is _not_ specified, then a regular file-to-file copy is done.
|
||||||
*/
|
*/
|
||||||
int main(int argc, char **argv)
|
int main(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
char *commit_id;
|
int commits;
|
||||||
|
const char **write_ref = NULL;
|
||||||
|
char **commit_id;
|
||||||
int arg = 1;
|
int arg = 1;
|
||||||
|
|
||||||
setup_git_directory();
|
setup_git_directory();
|
||||||
@ -229,21 +232,30 @@ int main(int argc, char **argv)
|
|||||||
else if (argv[arg][1] == 'v')
|
else if (argv[arg][1] == 'v')
|
||||||
get_verbosely = 1;
|
get_verbosely = 1;
|
||||||
else if (argv[arg][1] == 'w')
|
else if (argv[arg][1] == 'w')
|
||||||
write_ref = argv[++arg];
|
write_ref = &argv[++arg];
|
||||||
else if (!strcmp(argv[arg], "--recover"))
|
else if (!strcmp(argv[arg], "--recover"))
|
||||||
get_recover = 1;
|
get_recover = 1;
|
||||||
|
else if (!strcmp(argv[arg], "--stdin"))
|
||||||
|
commits_on_stdin = 1;
|
||||||
else
|
else
|
||||||
usage(local_pull_usage);
|
usage(local_pull_usage);
|
||||||
arg++;
|
arg++;
|
||||||
}
|
}
|
||||||
if (argc < arg + 2)
|
if (argc < arg + 2 - commits_on_stdin)
|
||||||
usage(local_pull_usage);
|
usage(local_pull_usage);
|
||||||
commit_id = argv[arg];
|
if (commits_on_stdin) {
|
||||||
path = argv[arg + 1];
|
commits = pull_targets_stdin(&commit_id, &write_ref);
|
||||||
write_ref_log_details = path;
|
} else {
|
||||||
|
commit_id = (char **) &argv[arg++];
|
||||||
|
commits = 1;
|
||||||
|
}
|
||||||
|
path = argv[arg];
|
||||||
|
|
||||||
if (pull(commit_id))
|
if (pull(commits, commit_id, write_ref, path))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
if (commits_on_stdin)
|
||||||
|
pull_targets_free(commits, commit_id, write_ref);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
10
log-tree.c
10
log-tree.c
@ -97,6 +97,11 @@ void show_log(struct rev_info *opt, const char *sep)
|
|||||||
subject = "Subject: ";
|
subject = "Subject: ";
|
||||||
|
|
||||||
printf("From %s Mon Sep 17 00:00:00 2001\n", sha1);
|
printf("From %s Mon Sep 17 00:00:00 2001\n", sha1);
|
||||||
|
if (opt->message_id)
|
||||||
|
printf("Message-Id: <%s>\n", opt->message_id);
|
||||||
|
if (opt->ref_message_id)
|
||||||
|
printf("In-Reply-To: <%s>\nReferences: <%s>\n",
|
||||||
|
opt->ref_message_id, opt->ref_message_id);
|
||||||
if (opt->mime_boundary) {
|
if (opt->mime_boundary) {
|
||||||
static char subject_buffer[1024];
|
static char subject_buffer[1024];
|
||||||
static char buffer[1024];
|
static char buffer[1024];
|
||||||
@ -129,7 +134,8 @@ void show_log(struct rev_info *opt, const char *sep)
|
|||||||
opt->diffopt.stat_sep = buffer;
|
opt->diffopt.stat_sep = buffer;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("%s%s",
|
printf("%s%s%s",
|
||||||
|
diff_get_color(opt->diffopt.color_diff, DIFF_COMMIT),
|
||||||
opt->commit_format == CMIT_FMT_ONELINE ? "" : "commit ",
|
opt->commit_format == CMIT_FMT_ONELINE ? "" : "commit ",
|
||||||
diff_unique_abbrev(commit->object.sha1, abbrev_commit));
|
diff_unique_abbrev(commit->object.sha1, abbrev_commit));
|
||||||
if (opt->parents)
|
if (opt->parents)
|
||||||
@ -138,6 +144,8 @@ void show_log(struct rev_info *opt, const char *sep)
|
|||||||
printf(" (from %s)",
|
printf(" (from %s)",
|
||||||
diff_unique_abbrev(parent->object.sha1,
|
diff_unique_abbrev(parent->object.sha1,
|
||||||
abbrev_commit));
|
abbrev_commit));
|
||||||
|
printf("%s",
|
||||||
|
diff_get_color(opt->diffopt.color_diff, DIFF_RESET));
|
||||||
putchar(opt->commit_format == CMIT_FMT_ONELINE ? ' ' : '\n');
|
putchar(opt->commit_format == CMIT_FMT_ONELINE ? ' ' : '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +63,7 @@ static const char *base_name;
|
|||||||
static unsigned char pack_file_sha1[20];
|
static unsigned char pack_file_sha1[20];
|
||||||
static int progress = 1;
|
static int progress = 1;
|
||||||
static volatile sig_atomic_t progress_update = 0;
|
static volatile sig_atomic_t progress_update = 0;
|
||||||
|
static int window = 10;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The object names in objects array are hashed with this hashtable,
|
* The object names in objects array are hashed with this hashtable,
|
||||||
@ -1216,16 +1217,26 @@ static void setup_progress_signal(void)
|
|||||||
setitimer(ITIMER_REAL, &v, NULL);
|
setitimer(ITIMER_REAL, &v, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int git_pack_config(const char *k, const char *v)
|
||||||
|
{
|
||||||
|
if(!strcmp(k, "pack.window")) {
|
||||||
|
window = git_config_int(k, v);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return git_default_config(k, v);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
SHA_CTX ctx;
|
SHA_CTX ctx;
|
||||||
char line[40 + 1 + PATH_MAX + 2];
|
char line[40 + 1 + PATH_MAX + 2];
|
||||||
int window = 10, depth = 10, pack_to_stdout = 0;
|
int depth = 10, pack_to_stdout = 0;
|
||||||
struct object_entry **list;
|
struct object_entry **list;
|
||||||
int num_preferred_base = 0;
|
int num_preferred_base = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
setup_git_directory();
|
setup_git_directory();
|
||||||
|
git_config(git_pack_config);
|
||||||
|
|
||||||
progress = isatty(2);
|
progress = isatty(2);
|
||||||
for (i = 1; i < argc; i++) {
|
for (i = 1; i < argc; i++) {
|
||||||
|
39
read-cache.c
39
read-cache.c
@ -319,6 +319,45 @@ int remove_file_from_cache(const char *path)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int add_file_to_index(const char *path, int verbose)
|
||||||
|
{
|
||||||
|
int size, namelen;
|
||||||
|
struct stat st;
|
||||||
|
struct cache_entry *ce;
|
||||||
|
|
||||||
|
if (lstat(path, &st))
|
||||||
|
die("%s: unable to stat (%s)", path, strerror(errno));
|
||||||
|
|
||||||
|
if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode))
|
||||||
|
die("%s: can only add regular files or symbolic links", path);
|
||||||
|
|
||||||
|
namelen = strlen(path);
|
||||||
|
size = cache_entry_size(namelen);
|
||||||
|
ce = xcalloc(1, size);
|
||||||
|
memcpy(ce->name, path, namelen);
|
||||||
|
ce->ce_flags = htons(namelen);
|
||||||
|
fill_stat_cache_info(ce, &st);
|
||||||
|
|
||||||
|
ce->ce_mode = create_ce_mode(st.st_mode);
|
||||||
|
if (!trust_executable_bit) {
|
||||||
|
/* If there is an existing entry, pick the mode bits
|
||||||
|
* from it.
|
||||||
|
*/
|
||||||
|
int pos = cache_name_pos(path, namelen);
|
||||||
|
if (pos >= 0)
|
||||||
|
ce->ce_mode = active_cache[pos]->ce_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index_path(ce->sha1, path, &st, 1))
|
||||||
|
die("unable to index file %s", path);
|
||||||
|
if (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD))
|
||||||
|
die("unable to add %s to index",path);
|
||||||
|
if (verbose)
|
||||||
|
printf("add '%s'\n", path);
|
||||||
|
cache_tree_invalidate_path(active_cache_tree, path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int ce_same_name(struct cache_entry *a, struct cache_entry *b)
|
int ce_same_name(struct cache_entry *a, struct cache_entry *b)
|
||||||
{
|
{
|
||||||
int len = ce_namelen(a);
|
int len = ce_namelen(a);
|
||||||
|
5
refs.c
5
refs.c
@ -294,6 +294,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *path,
|
|||||||
int plen,
|
int plen,
|
||||||
const unsigned char *old_sha1, int mustexist)
|
const unsigned char *old_sha1, int mustexist)
|
||||||
{
|
{
|
||||||
|
const char *orig_path = path;
|
||||||
struct ref_lock *lock;
|
struct ref_lock *lock;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
@ -303,7 +304,11 @@ static struct ref_lock *lock_ref_sha1_basic(const char *path,
|
|||||||
plen = strlen(path) - plen;
|
plen = strlen(path) - plen;
|
||||||
path = resolve_ref(path, lock->old_sha1, mustexist);
|
path = resolve_ref(path, lock->old_sha1, mustexist);
|
||||||
if (!path) {
|
if (!path) {
|
||||||
|
int last_errno = errno;
|
||||||
|
error("unable to resolve reference %s: %s",
|
||||||
|
orig_path, strerror(errno));
|
||||||
unlock_ref(lock);
|
unlock_ref(lock);
|
||||||
|
errno = last_errno;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
lock->lk = xcalloc(1, sizeof(struct lock_file));
|
lock->lk = xcalloc(1, sizeof(struct lock_file));
|
||||||
|
@ -509,7 +509,7 @@ static int add_parents_only(struct rev_info *revs, const char *arg, int flags)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_revisions(struct rev_info *revs)
|
void init_revisions(struct rev_info *revs, const char *prefix)
|
||||||
{
|
{
|
||||||
memset(revs, 0, sizeof(*revs));
|
memset(revs, 0, sizeof(*revs));
|
||||||
|
|
||||||
@ -521,7 +521,7 @@ void init_revisions(struct rev_info *revs)
|
|||||||
revs->pruning.change = file_change;
|
revs->pruning.change = file_change;
|
||||||
revs->lifo = 1;
|
revs->lifo = 1;
|
||||||
revs->dense = 1;
|
revs->dense = 1;
|
||||||
revs->prefix = setup_git_directory();
|
revs->prefix = prefix;
|
||||||
revs->max_age = -1;
|
revs->max_age = -1;
|
||||||
revs->min_age = -1;
|
revs->min_age = -1;
|
||||||
revs->max_count = -1;
|
revs->max_count = -1;
|
||||||
|
@ -61,6 +61,8 @@ struct rev_info {
|
|||||||
struct log_info *loginfo;
|
struct log_info *loginfo;
|
||||||
int nr, total;
|
int nr, total;
|
||||||
const char *mime_boundary;
|
const char *mime_boundary;
|
||||||
|
const char *message_id;
|
||||||
|
const char *ref_message_id;
|
||||||
const char *add_signoff;
|
const char *add_signoff;
|
||||||
const char *extra_headers;
|
const char *extra_headers;
|
||||||
|
|
||||||
@ -85,7 +87,7 @@ struct rev_info {
|
|||||||
extern int rev_same_tree_as_empty(struct rev_info *, struct tree *t1);
|
extern int rev_same_tree_as_empty(struct rev_info *, struct tree *t1);
|
||||||
extern int rev_compare_tree(struct rev_info *, struct tree *t1, struct tree *t2);
|
extern int rev_compare_tree(struct rev_info *, struct tree *t1, struct tree *t2);
|
||||||
|
|
||||||
extern void init_revisions(struct rev_info *revs);
|
extern void init_revisions(struct rev_info *revs, const char *prefix);
|
||||||
extern int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def);
|
extern int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def);
|
||||||
extern void prepare_revision_walk(struct rev_info *revs);
|
extern void prepare_revision_walk(struct rev_info *revs);
|
||||||
extern struct commit *get_revision(struct rev_info *revs);
|
extern struct commit *get_revision(struct rev_info *revs);
|
||||||
|
4
setup.c
4
setup.c
@ -184,6 +184,10 @@ const char *setup_git_directory_gently(int *nongit_ok)
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
bad_dir_environ:
|
bad_dir_environ:
|
||||||
|
if (!nongit_ok) {
|
||||||
|
*nongit_ok = 1;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
path[len] = 0;
|
path[len] = 0;
|
||||||
die("Not a git repository: '%s'", path);
|
die("Not a git repository: '%s'", path);
|
||||||
}
|
}
|
||||||
|
112
sha1_file.c
112
sha1_file.c
@ -684,26 +684,74 @@ static void *map_sha1_file_internal(const unsigned char *sha1,
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int unpack_sha1_header(z_stream *stream, void *map, unsigned long mapsize, void *buffer, unsigned long size)
|
static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz)
|
||||||
{
|
{
|
||||||
|
unsigned char c;
|
||||||
|
unsigned int word, bits;
|
||||||
|
unsigned long size;
|
||||||
|
static const char *typename[8] = {
|
||||||
|
NULL, /* OBJ_EXT */
|
||||||
|
"commit", "tree", "blob", "tag",
|
||||||
|
NULL, NULL, NULL
|
||||||
|
};
|
||||||
|
const char *type;
|
||||||
|
|
||||||
/* Get the data stream */
|
/* Get the data stream */
|
||||||
memset(stream, 0, sizeof(*stream));
|
memset(stream, 0, sizeof(*stream));
|
||||||
stream->next_in = map;
|
stream->next_in = map;
|
||||||
stream->avail_in = mapsize;
|
stream->avail_in = mapsize;
|
||||||
stream->next_out = buffer;
|
stream->next_out = buffer;
|
||||||
stream->avail_out = size;
|
stream->avail_out = bufsiz;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Is it a zlib-compressed buffer? If so, the first byte
|
||||||
|
* must be 0x78 (15-bit window size, deflated), and the
|
||||||
|
* first 16-bit word is evenly divisible by 31
|
||||||
|
*/
|
||||||
|
word = (map[0] << 8) + map[1];
|
||||||
|
if (map[0] == 0x78 && !(word % 31)) {
|
||||||
inflateInit(stream);
|
inflateInit(stream);
|
||||||
return inflate(stream, 0);
|
return inflate(stream, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c = *map++;
|
||||||
|
mapsize--;
|
||||||
|
type = typename[(c >> 4) & 7];
|
||||||
|
if (!type)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
bits = 4;
|
||||||
|
size = c & 0xf;
|
||||||
|
while ((c & 0x80)) {
|
||||||
|
if (bits >= 8*sizeof(long))
|
||||||
|
return -1;
|
||||||
|
c = *map++;
|
||||||
|
size += (c & 0x7f) << bits;
|
||||||
|
bits += 7;
|
||||||
|
mapsize--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set up the stream for the rest.. */
|
||||||
|
stream->next_in = map;
|
||||||
|
stream->avail_in = mapsize;
|
||||||
|
inflateInit(stream);
|
||||||
|
|
||||||
|
/* And generate the fake traditional header */
|
||||||
|
stream->total_out = 1 + snprintf(buffer, bufsiz, "%s %lu", type, size);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void *unpack_sha1_rest(z_stream *stream, void *buffer, unsigned long size)
|
static void *unpack_sha1_rest(z_stream *stream, void *buffer, unsigned long size)
|
||||||
{
|
{
|
||||||
int bytes = strlen(buffer) + 1;
|
int bytes = strlen(buffer) + 1;
|
||||||
unsigned char *buf = xmalloc(1+size);
|
unsigned char *buf = xmalloc(1+size);
|
||||||
|
unsigned long n;
|
||||||
|
|
||||||
memcpy(buf, (char *) buffer + bytes, stream->total_out - bytes);
|
n = stream->total_out - bytes;
|
||||||
bytes = stream->total_out - bytes;
|
if (n > size)
|
||||||
|
n = size;
|
||||||
|
memcpy(buf, (char *) buffer + bytes, n);
|
||||||
|
bytes = n;
|
||||||
if (bytes < size) {
|
if (bytes < size) {
|
||||||
stream->next_out = buf + bytes;
|
stream->next_out = buf + bytes;
|
||||||
stream->avail_out = size - bytes;
|
stream->avail_out = size - bytes;
|
||||||
@ -1331,21 +1379,20 @@ char *write_sha1_file_prepare(void *buf,
|
|||||||
static int link_temp_to_file(const char *tmpfile, char *filename)
|
static int link_temp_to_file(const char *tmpfile, char *filename)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
char *dir;
|
||||||
|
|
||||||
if (!link(tmpfile, filename))
|
if (!link(tmpfile, filename))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to mkdir the last path component if that failed
|
* Try to mkdir the last path component if that failed.
|
||||||
* with an ENOENT.
|
|
||||||
*
|
*
|
||||||
* Re-try the "link()" regardless of whether the mkdir
|
* Re-try the "link()" regardless of whether the mkdir
|
||||||
* succeeds, since a race might mean that somebody
|
* succeeds, since a race might mean that somebody
|
||||||
* else succeeded.
|
* else succeeded.
|
||||||
*/
|
*/
|
||||||
ret = errno;
|
ret = errno;
|
||||||
if (ret == ENOENT) {
|
dir = strrchr(filename, '/');
|
||||||
char *dir = strrchr(filename, '/');
|
|
||||||
if (dir) {
|
if (dir) {
|
||||||
*dir = 0;
|
*dir = 0;
|
||||||
mkdir(filename, 0777);
|
mkdir(filename, 0777);
|
||||||
@ -1356,7 +1403,6 @@ static int link_temp_to_file(const char *tmpfile, char *filename)
|
|||||||
return 0;
|
return 0;
|
||||||
ret = errno;
|
ret = errno;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1414,6 +1460,49 @@ static int write_buffer(int fd, const void *buf, size_t len)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int write_binary_header(unsigned char *hdr, enum object_type type, unsigned long len)
|
||||||
|
{
|
||||||
|
int hdr_len;
|
||||||
|
unsigned char c;
|
||||||
|
|
||||||
|
c = (type << 4) | (len & 15);
|
||||||
|
len >>= 4;
|
||||||
|
hdr_len = 1;
|
||||||
|
while (len) {
|
||||||
|
*hdr++ = c | 0x80;
|
||||||
|
hdr_len++;
|
||||||
|
c = (len & 0x7f);
|
||||||
|
len >>= 7;
|
||||||
|
}
|
||||||
|
*hdr = c;
|
||||||
|
return hdr_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setup_object_header(z_stream *stream, const char *type, unsigned long len)
|
||||||
|
{
|
||||||
|
int obj_type, hdr;
|
||||||
|
|
||||||
|
if (use_legacy_headers) {
|
||||||
|
while (deflate(stream, 0) == Z_OK)
|
||||||
|
/* nothing */;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!strcmp(type, blob_type))
|
||||||
|
obj_type = OBJ_BLOB;
|
||||||
|
else if (!strcmp(type, tree_type))
|
||||||
|
obj_type = OBJ_TREE;
|
||||||
|
else if (!strcmp(type, commit_type))
|
||||||
|
obj_type = OBJ_COMMIT;
|
||||||
|
else if (!strcmp(type, tag_type))
|
||||||
|
obj_type = OBJ_TAG;
|
||||||
|
else
|
||||||
|
die("trying to generate bogus object of type '%s'", type);
|
||||||
|
hdr = write_binary_header(stream->next_out, obj_type, len);
|
||||||
|
stream->total_out = hdr;
|
||||||
|
stream->next_out += hdr;
|
||||||
|
stream->avail_out -= hdr;
|
||||||
|
}
|
||||||
|
|
||||||
int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *returnsha1)
|
int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *returnsha1)
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
@ -1459,7 +1548,7 @@ int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned cha
|
|||||||
/* Set it up */
|
/* Set it up */
|
||||||
memset(&stream, 0, sizeof(stream));
|
memset(&stream, 0, sizeof(stream));
|
||||||
deflateInit(&stream, zlib_compression_level);
|
deflateInit(&stream, zlib_compression_level);
|
||||||
size = deflateBound(&stream, len+hdrlen);
|
size = 8 + deflateBound(&stream, len+hdrlen);
|
||||||
compressed = xmalloc(size);
|
compressed = xmalloc(size);
|
||||||
|
|
||||||
/* Compress it */
|
/* Compress it */
|
||||||
@ -1469,8 +1558,7 @@ int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned cha
|
|||||||
/* First header.. */
|
/* First header.. */
|
||||||
stream.next_in = hdr;
|
stream.next_in = hdr;
|
||||||
stream.avail_in = hdrlen;
|
stream.avail_in = hdrlen;
|
||||||
while (deflate(&stream, 0) == Z_OK)
|
setup_object_header(&stream, type, len);
|
||||||
/* nothing */;
|
|
||||||
|
|
||||||
/* Then the data itself.. */
|
/* Then the data itself.. */
|
||||||
stream.next_in = buf;
|
stream.next_in = buf;
|
||||||
|
@ -120,9 +120,10 @@ int fetch_ref(char *ref, unsigned char *sha1)
|
|||||||
|
|
||||||
static const char ssh_fetch_usage[] =
|
static const char ssh_fetch_usage[] =
|
||||||
MY_PROGRAM_NAME
|
MY_PROGRAM_NAME
|
||||||
" [-c] [-t] [-a] [-v] [-d] [--recover] [-w ref] commit-id url";
|
" [-c] [-t] [-a] [-v] [--recover] [-w ref] commit-id url";
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
const char *write_ref = NULL;
|
||||||
char *commit_id;
|
char *commit_id;
|
||||||
char *url;
|
char *url;
|
||||||
int arg = 1;
|
int arg = 1;
|
||||||
@ -159,7 +160,6 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
commit_id = argv[arg];
|
commit_id = argv[arg];
|
||||||
url = argv[arg + 1];
|
url = argv[arg + 1];
|
||||||
write_ref_log_details = url;
|
|
||||||
|
|
||||||
if (setup_connection(&fd_in, &fd_out, prog, url, arg, argv + 1))
|
if (setup_connection(&fd_in, &fd_out, prog, url, arg, argv + 1))
|
||||||
return 1;
|
return 1;
|
||||||
@ -167,7 +167,7 @@ int main(int argc, char **argv)
|
|||||||
if (get_version())
|
if (get_version())
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (pull(commit_id))
|
if (pull(1, &commit_id, &write_ref, url))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -14,6 +14,8 @@ D=4444444444444444444444444444444444444444
|
|||||||
E=5555555555555555555555555555555555555555
|
E=5555555555555555555555555555555555555555
|
||||||
F=6666666666666666666666666666666666666666
|
F=6666666666666666666666666666666666666666
|
||||||
m=refs/heads/master
|
m=refs/heads/master
|
||||||
|
n_dir=refs/heads/gu
|
||||||
|
n=$n_dir/fixes
|
||||||
|
|
||||||
test_expect_success \
|
test_expect_success \
|
||||||
"create $m" \
|
"create $m" \
|
||||||
@ -25,6 +27,16 @@ test_expect_success \
|
|||||||
test $B = $(cat .git/$m)'
|
test $B = $(cat .git/$m)'
|
||||||
rm -f .git/$m
|
rm -f .git/$m
|
||||||
|
|
||||||
|
test_expect_success \
|
||||||
|
"fail to create $n" \
|
||||||
|
'touch .git/$n_dir
|
||||||
|
git-update-ref $n $A >out 2>err
|
||||||
|
test $? = 1 &&
|
||||||
|
test "" = "$(cat out)" &&
|
||||||
|
grep "error: unable to resolve reference" err &&
|
||||||
|
grep $n err'
|
||||||
|
rm -f .git/$n_dir out err
|
||||||
|
|
||||||
test_expect_success \
|
test_expect_success \
|
||||||
"create $m (by HEAD)" \
|
"create $m (by HEAD)" \
|
||||||
'git-update-ref HEAD $A &&
|
'git-update-ref HEAD $A &&
|
||||||
|
@ -13,8 +13,8 @@ test_description='git-apply handling copy/rename patch.
|
|||||||
cat >test-patch <<\EOF
|
cat >test-patch <<\EOF
|
||||||
diff --git a/foo b/bar
|
diff --git a/foo b/bar
|
||||||
similarity index 47%
|
similarity index 47%
|
||||||
copy from foo
|
rename from foo
|
||||||
copy to bar
|
rename to bar
|
||||||
--- a/foo
|
--- a/foo
|
||||||
+++ b/bar
|
+++ b/bar
|
||||||
@@ -1 +1 @@
|
@@ -1 +1 @@
|
||||||
@ -39,4 +39,24 @@ else
|
|||||||
'test -f bar && ls -l bar | grep "^-..x......"'
|
'test -f bar && ls -l bar | grep "^-..x......"'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
test_expect_success 'apply reverse' \
|
||||||
|
'git-apply -R --index --stat --summary --apply test-patch &&
|
||||||
|
test "$(cat foo)" = "This is foo"'
|
||||||
|
|
||||||
|
cat >test-patch <<\EOF
|
||||||
|
diff --git a/foo b/bar
|
||||||
|
similarity index 47%
|
||||||
|
copy from foo
|
||||||
|
copy to bar
|
||||||
|
--- a/foo
|
||||||
|
+++ b/bar
|
||||||
|
@@ -1 +1 @@
|
||||||
|
-This is foo
|
||||||
|
+This is bar
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_expect_success 'apply copy' \
|
||||||
|
'git-apply --index --stat --summary --apply test-patch &&
|
||||||
|
test "$(cat bar)" = "This is bar" -a "$(cat foo)" = "This is foo"'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
@ -35,8 +35,8 @@ git-commit -m 'Second Version'
|
|||||||
git-diff-tree -p master binary >B.diff
|
git-diff-tree -p master binary >B.diff
|
||||||
git-diff-tree -p -C master binary >C.diff
|
git-diff-tree -p -C master binary >C.diff
|
||||||
|
|
||||||
git-diff-tree -p --full-index master binary >BF.diff
|
git-diff-tree -p --binary master binary >BF.diff
|
||||||
git-diff-tree -p --full-index -C master binary >CF.diff
|
git-diff-tree -p --binary -C master binary >CF.diff
|
||||||
|
|
||||||
test_expect_success 'stat binary diff -- should not fail.' \
|
test_expect_success 'stat binary diff -- should not fail.' \
|
||||||
'git-checkout master
|
'git-checkout master
|
||||||
|
@ -11,31 +11,7 @@ test_description='git-apply should not get confused with rename/copy.
|
|||||||
|
|
||||||
# setup
|
# setup
|
||||||
|
|
||||||
mkdir -p include/arch/x86_64/klibc klibc/arch/x86_64/include/klibc
|
mkdir -p klibc/arch/x86_64/include/klibc
|
||||||
|
|
||||||
cat >include/arch/x86_64/klibc/archsetjmp.h <<\EOF
|
|
||||||
/*
|
|
||||||
* arch/x86_64/include/klibc/archsetjmp.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _KLIBC_ARCHSETJMP_H
|
|
||||||
#define _KLIBC_ARCHSETJMP_H
|
|
||||||
|
|
||||||
struct __jmp_buf {
|
|
||||||
unsigned long __rbx;
|
|
||||||
unsigned long __rsp;
|
|
||||||
unsigned long __rbp;
|
|
||||||
unsigned long __r12;
|
|
||||||
unsigned long __r13;
|
|
||||||
unsigned long __r14;
|
|
||||||
unsigned long __r15;
|
|
||||||
unsigned long __rip;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct __jmp_buf jmp_buf[1];
|
|
||||||
|
|
||||||
#endif /* _SETJMP_H */
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cat >klibc/arch/x86_64/include/klibc/archsetjmp.h <<\EOF
|
cat >klibc/arch/x86_64/include/klibc/archsetjmp.h <<\EOF
|
||||||
/*
|
/*
|
||||||
@ -139,7 +115,7 @@ rename to include/arch/m32r/klibc/archsetjmp.h
|
|||||||
+#endif /* _KLIBC_ARCHSETJMP_H */
|
+#endif /* _KLIBC_ARCHSETJMP_H */
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
find include klibc -type f -print | xargs git-update-index --add --
|
find klibc -type f -print | xargs git-update-index --add --
|
||||||
|
|
||||||
test_expect_success 'check rename/copy patch' 'git-apply --check patch'
|
test_expect_success 'check rename/copy patch' 'git-apply --check patch'
|
||||||
|
|
||||||
|
105
t/t4114-apply-typechange.sh
Executable file
105
t/t4114-apply-typechange.sh
Executable file
@ -0,0 +1,105 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright (c) 2006 Eric Wong
|
||||||
|
#
|
||||||
|
|
||||||
|
test_description='git-apply should not get confused with type changes.
|
||||||
|
|
||||||
|
'
|
||||||
|
|
||||||
|
. ./test-lib.sh
|
||||||
|
|
||||||
|
test_expect_success 'setup repository and commits' '
|
||||||
|
echo "hello world" > foo &&
|
||||||
|
echo "hi planet" > bar &&
|
||||||
|
git update-index --add foo bar &&
|
||||||
|
git commit -m initial &&
|
||||||
|
git branch initial &&
|
||||||
|
rm -f foo &&
|
||||||
|
ln -s bar foo &&
|
||||||
|
git update-index foo &&
|
||||||
|
git commit -m "foo symlinked to bar" &&
|
||||||
|
git branch foo-symlinked-to-bar &&
|
||||||
|
rm -f foo &&
|
||||||
|
echo "how far is the sun?" > foo &&
|
||||||
|
git update-index foo &&
|
||||||
|
git commit -m "foo back to file" &&
|
||||||
|
git branch foo-back-to-file &&
|
||||||
|
rm -f foo &&
|
||||||
|
git update-index --remove foo &&
|
||||||
|
mkdir foo &&
|
||||||
|
echo "if only I knew" > foo/baz &&
|
||||||
|
git update-index --add foo/baz &&
|
||||||
|
git commit -m "foo becomes a directory" &&
|
||||||
|
git branch "foo-becomes-a-directory" &&
|
||||||
|
echo "hello world" > foo/baz &&
|
||||||
|
git update-index foo/baz &&
|
||||||
|
git commit -m "foo/baz is the original foo" &&
|
||||||
|
git branch foo-baz-renamed-from-foo
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'file renamed from foo to foo/baz' '
|
||||||
|
git checkout -f initial &&
|
||||||
|
git diff-tree -M -p HEAD foo-baz-renamed-from-foo > patch &&
|
||||||
|
git apply --index < patch
|
||||||
|
'
|
||||||
|
test_debug 'cat patch'
|
||||||
|
|
||||||
|
|
||||||
|
test_expect_success 'file renamed from foo/baz to foo' '
|
||||||
|
git checkout -f foo-baz-renamed-from-foo &&
|
||||||
|
git diff-tree -M -p HEAD initial > patch &&
|
||||||
|
git apply --index < patch
|
||||||
|
'
|
||||||
|
test_debug 'cat patch'
|
||||||
|
|
||||||
|
|
||||||
|
test_expect_success 'directory becomes file' '
|
||||||
|
git checkout -f foo-becomes-a-directory &&
|
||||||
|
git diff-tree -p HEAD initial > patch &&
|
||||||
|
git apply --index < patch
|
||||||
|
'
|
||||||
|
test_debug 'cat patch'
|
||||||
|
|
||||||
|
|
||||||
|
test_expect_success 'file becomes directory' '
|
||||||
|
git checkout -f initial &&
|
||||||
|
git diff-tree -p HEAD foo-becomes-a-directory > patch &&
|
||||||
|
git apply --index < patch
|
||||||
|
'
|
||||||
|
test_debug 'cat patch'
|
||||||
|
|
||||||
|
|
||||||
|
test_expect_success 'file becomes symlink' '
|
||||||
|
git checkout -f initial &&
|
||||||
|
git diff-tree -p HEAD foo-symlinked-to-bar > patch &&
|
||||||
|
git apply --index < patch
|
||||||
|
'
|
||||||
|
test_debug 'cat patch'
|
||||||
|
|
||||||
|
|
||||||
|
test_expect_success 'symlink becomes file' '
|
||||||
|
git checkout -f foo-symlinked-to-bar &&
|
||||||
|
git diff-tree -p HEAD foo-back-to-file > patch &&
|
||||||
|
git apply --index < patch
|
||||||
|
'
|
||||||
|
test_debug 'cat patch'
|
||||||
|
|
||||||
|
|
||||||
|
test_expect_success 'symlink becomes directory' '
|
||||||
|
git checkout -f foo-symlinked-to-bar &&
|
||||||
|
git diff-tree -p HEAD foo-becomes-a-directory > patch &&
|
||||||
|
git apply --index < patch
|
||||||
|
'
|
||||||
|
test_debug 'cat patch'
|
||||||
|
|
||||||
|
|
||||||
|
test_expect_success 'directory becomes symlink' '
|
||||||
|
git checkout -f foo-becomes-a-directory &&
|
||||||
|
git diff-tree -p HEAD foo-symlinked-to-bar > patch &&
|
||||||
|
git apply --index < patch
|
||||||
|
'
|
||||||
|
test_debug 'cat patch'
|
||||||
|
|
||||||
|
|
||||||
|
test_done
|
19
t/t6004-rev-list-path-optim.sh
Executable file
19
t/t6004-rev-list-path-optim.sh
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
test_description='git-rev-list trivial path optimization test'
|
||||||
|
|
||||||
|
. ./test-lib.sh
|
||||||
|
|
||||||
|
test_expect_success setup '
|
||||||
|
echo Hello > a &&
|
||||||
|
git add a &&
|
||||||
|
git commit -m "Initial commit" a
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success path-optimization '
|
||||||
|
commit=$(echo "Unchanged tree" | git-commit-tree "HEAD^{tree}" -p HEAD) &&
|
||||||
|
test $(git-rev-list $commit | wc -l) = 2 &&
|
||||||
|
test $(git-rev-list $commit -- . | wc -l) = 1
|
||||||
|
'
|
||||||
|
|
||||||
|
test_done
|
@ -38,4 +38,44 @@ test_expect_success \
|
|||||||
'git-diff-tree -r -M --name-status HEAD^ HEAD | \
|
'git-diff-tree -r -M --name-status HEAD^ HEAD | \
|
||||||
grep -E "^R100.+path1/COPYING.+path0/COPYING"'
|
grep -E "^R100.+path1/COPYING.+path0/COPYING"'
|
||||||
|
|
||||||
|
test_expect_success \
|
||||||
|
'adding another file' \
|
||||||
|
'cp ../../README path0/README &&
|
||||||
|
git-add path0/README &&
|
||||||
|
git-commit -m add2 -a'
|
||||||
|
|
||||||
|
test_expect_success \
|
||||||
|
'moving whole subdirectory' \
|
||||||
|
'git-mv path0 path2'
|
||||||
|
|
||||||
|
test_expect_success \
|
||||||
|
'commiting the change' \
|
||||||
|
'git-commit -m dir-move -a'
|
||||||
|
|
||||||
|
test_expect_success \
|
||||||
|
'checking the commit' \
|
||||||
|
'git-diff-tree -r -M --name-status HEAD^ HEAD | \
|
||||||
|
grep -E "^R100.+path0/COPYING.+path2/COPYING" &&
|
||||||
|
git-diff-tree -r -M --name-status HEAD^ HEAD | \
|
||||||
|
grep -E "^R100.+path0/README.+path2/README"'
|
||||||
|
|
||||||
|
test_expect_success \
|
||||||
|
'moving whole subdirectory into subdirectory' \
|
||||||
|
'git-mv path2 path1'
|
||||||
|
|
||||||
|
test_expect_success \
|
||||||
|
'commiting the change' \
|
||||||
|
'git-commit -m dir-move -a'
|
||||||
|
|
||||||
|
test_expect_success \
|
||||||
|
'checking the commit' \
|
||||||
|
'git-diff-tree -r -M --name-status HEAD^ HEAD | \
|
||||||
|
grep -E "^R100.+path2/COPYING.+path1/path2/COPYING" &&
|
||||||
|
git-diff-tree -r -M --name-status HEAD^ HEAD | \
|
||||||
|
grep -E "^R100.+path2/README.+path1/path2/README"'
|
||||||
|
|
||||||
|
test_expect_failure \
|
||||||
|
'do not move directory over existing directory' \
|
||||||
|
'mkdir path0 && mkdir path0/path2 && git-mv path2 path0'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
@ -241,11 +241,6 @@ static void unpack_one(unsigned nr, unsigned total)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* We unpack from the end, older files first. Now, usually
|
|
||||||
* there are deltas etc, so we'll not actually write the
|
|
||||||
* objects in that order, but we might as well try..
|
|
||||||
*/
|
|
||||||
static void unpack_all(void)
|
static void unpack_all(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user