Merge branch 'master' into js/c-merge-recursive

Adjust to hold_lock_file_for_update() change on the master.
This commit is contained in:
Junio C Hamano 2006-08-12 18:34:36 -07:00
commit eed94a570e
84 changed files with 1487 additions and 480 deletions

View File

@ -83,9 +83,12 @@ core.repositoryFormatVersion::
version.
core.sharedRepository::
If true, the repository is made shareable between several users
in a group (making sure all the files and objects are group-writable).
See gitlink:git-init-db[1]. False by default.
When 'group' (or 'true'), the repository is made shareable between
several users in a group (making sure all the files and objects are
group-writable). When 'all' (or 'world' or 'everybody'), the
repository will be readable by all users, additionally to being
group-shareable. When 'umask' (or 'false'), git will use permissions
reported by umask(2). See gitlink:git-init-db[1]. False by default.
core.warnAmbiguousRefs::
If true, git will warn you if the ref name you passed it is ambiguous
@ -116,6 +119,10 @@ apply.whitespace::
Tells `git-apply` how to handle whitespaces, in the same way
as the '--whitespace' option. See gitlink:git-apply[1].
pager.color::
A boolean to enable/disable colored output when the pager is in
use (default is true).
diff.color::
When true (or `always`), always use colors in patch.
When false (or `never`), never. When set to `auto`, use
@ -219,14 +226,14 @@ showbranch.default::
See gitlink:git-show-branch[1].
tar.umask::
By default, git-link:git-tar-tree[1] sets file and directories modes
By default, gitlink: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.
gitlink: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
the same permissions as gitlink:git-checkout[1] would use. The default
value remains 0, which means world read-write.
user.email::

View File

@ -116,7 +116,7 @@ file each time git-cvsimport is run.
+
It is not recommended to use this feature if you intend to
export changes back to CVS again later with
git-link[1]::git-cvsexportcommit.
gitlink:git-cvsexportcommit[1].
OUTPUT
------

View File

@ -16,7 +16,7 @@ SYNOPSIS
[-n] [-l | --files-with-matches] [-L | --files-without-match]
[-c | --count]
[-A <post-context>] [-B <pre-context>] [-C <context>]
[-f <file>] [-e] <pattern>
[-f <file>] [-e] <pattern> [--and|--or|--not|(|)|-e <pattern>...]
[<tree>...]
[--] [<path>...]
@ -74,16 +74,30 @@ OPTIONS
-e::
The next parameter is the pattern. This option has to be
used for patterns starting with - and should be used in
scripts passing user input to grep.
scripts passing user input to grep. Multiple patterns are
combined by 'or'.
--and | --or | --not | ( | )::
Specify how multiple patterns are combined using boolean
expressions. `--or` is the default operator. `--and` has
higher precedence than `--or`. `-e` has to be used for all
patterns.
`<tree>...`::
Search blobs in the trees for specified patterns.
`--`::
\--::
Signals the end of options; the rest of the parameters
are <path> limiters.
Example
-------
git grep -e \'#define\' --and \( -e MAX_PATH -e PATH_MAX \)::
Looks for a line that has `#define` and either `MAX_PATH` or
`PATH_MAX`.
Author
------
Originally written by Linus Torvalds <torvalds@osdl.org>, later

View File

@ -8,17 +8,47 @@ git-init-db - Creates an empty git repository
SYNOPSIS
--------
'git-init-db' [--template=<template_directory>] [--shared]
'git-init-db' [--template=<template_directory>] [--shared[=<permissions>]]
OPTIONS
-------
--template=<template_directory>::
Provide the directory from which templates will be used.
The default template directory is `/usr/share/git-core/templates`.
--shared::
Specify that the git repository is to be shared amongst several users.
--
--template=<template_directory>::
Provide the directory from which templates will be used. The default template
directory is `/usr/share/git-core/templates`.
When specified, `<template_directory>` is used as the source of the template
files rather than the default. The template files include some directory
structure, some suggested "exclude patterns", and copies of non-executing
"hook" files. The suggested patterns and hook files are all modifiable and
extensible.
--shared[={false|true|umask|group|all|world|everybody}]::
Specify that the git repository is to be shared amongst several users. This
allows users belonging to the same group to push into that
repository. When specified, the config variable "core.sharedRepository" is
set so that files and directories under `$GIT_DIR` are created with the
requested permissions. When not specified, git will use permissions reported
by umask(2).
The option can have the following values, defaulting to 'group' if no value
is given:
- 'umask' (or 'false'): Use permissions reported by umask(2). The default,
when `--shared` is not specified.
- 'group' (or 'true'): Make the repository group-writable, (and g+sx, since
the git group may be not the primary group of all users).
- 'all' (or 'world' or 'everybody'): Same as 'group', but make the repository
readable by all users.
--
DESCRIPTION
@ -29,12 +59,6 @@ template files.
An initial `HEAD` file that references the HEAD of the master branch
is also created.
If `--template=<template_directory>` is specified, `<template_directory>`
is used as the source of the template files rather than the default.
The template files include some directory structure, some suggested
"exclude patterns", and copies of non-executing "hook" files. The
suggested patterns and hook files are all modifiable and extensible.
If the `$GIT_DIR` environment variable is set then it specifies a path
to use instead of `./.git` for the base of the repository.
@ -42,11 +66,6 @@ If the object storage directory is specified via the `$GIT_OBJECT_DIRECTORY`
environment variable then the sha1 directories are created underneath -
otherwise the default `$GIT_DIR/objects` directory is used.
A shared repository allows users belonging to the same group to push into that
repository. When specifying `--shared` the config variable "core.sharedRepository"
is set to 'true' so that directories under `$GIT_DIR` are made group writable
(and g+sx, since the git group may be not the primary group of all users).
Running `git-init-db` in an existing repository is safe. It will not overwrite
things that are already there. The primary reason for rerunning `git-init-db`
is to pick up newly added templates.

View File

@ -8,7 +8,7 @@ git-push - Update remote refs along with associated objects
SYNOPSIS
--------
'git-push' [--all] [--tags] [--force] <repository> <refspec>...
'git-push' [--all] [--tags] [-f | --force] <repository> <refspec>...
DESCRIPTION
-----------

View File

@ -22,6 +22,7 @@ SYNOPSIS
[ [\--objects | \--objects-edge] [ \--unpacked ] ]
[ \--pretty | \--header ]
[ \--bisect ]
[ \--merge ]
<commit>... [ \-- <paths>... ]
DESCRIPTION
@ -123,6 +124,10 @@ OPTIONS
topological order (i.e. descendant commits are shown
before their parents).
--merge::
After a failed merge, show refs that touch files having a
conflict and don't exist on all heads to merge.
Author
------
Written by Linus Torvalds <torvalds@osdl.org>

View File

@ -8,7 +8,7 @@ git-status - Show working tree status
SYNOPSIS
--------
'git-status'
'git-status' <options>...
DESCRIPTION
-----------
@ -23,6 +23,10 @@ If there is no path that is different between the index file and
the current HEAD commit, the command exits with non-zero
status.
The command takes the same set of options as `git-commit`; it
shows what would be committed if the same options are given to
`git-commit`.
OUTPUT
------

View File

@ -397,6 +397,9 @@ gitlink:git-quiltimport[1]::
gitlink:git-relink[1]::
Hardlink common objects in local repositories.
gitlink:git-svn[1]::
Bidirectional operation between a single Subversion branch and git.
gitlink:git-svnimport[1]::
Import a SVN repository into git.
@ -442,6 +445,9 @@ gitlink:git-get-tar-commit-id[1]::
gitlink:git-imap-send[1]::
Dump a mailbox from stdin into an imap folder.
gitlink:git-instaweb[1]::
Instantly browse your working repository in gitweb.
gitlink:git-mailinfo[1]::
Extracts patch and authorship information from a single
e-mail message, optionally transliterating the commit

View File

@ -0,0 +1,256 @@
From: Rutger Nijlunsing <rutger@nospam.com>
Subject: Setting up a git repository which can be pushed into and pulled from over HTTP.
Date: Thu, 10 Aug 2006 22:00:26 +0200
Since Apache is one of those packages people like to compile
themselves while others prefer the bureaucrat's dream Debian, it is
impossible to give guidelines which will work for everyone. Just send
some feedback to the mailing list at git@vger.kernel.org to get this
document tailored to your favorite distro.
What's needed:
- Have an Apache web-server
On Debian:
$ apt-get install apache2
To get apache2 by default started,
edit /etc/default/apache2 and set NO_START=0
- can edit the configuration of it.
This could be found under /etc/httpd, or refer to your Apache documentation.
On Debian: this means being able to edit files under /etc/apache2
- can restart it.
'apachectl --graceful' might do. If it doesn't, just stop and
restart apache. Be warning that active connections to your server
might be aborted by this.
On Debian:
$ /etc/init.d/apache2 restart
or
$ /etc/init.d/apache2 force-reload
(which seems to do the same)
This adds symlinks from the /etc/apache2/mods-enabled to
/etc/apache2/mods-available.
- have permissions to chown a directory
- have git installed at the server _and_ client
In effect, this probably means you're going to be root.
Step 1: setup a bare GIT repository
-----------------------------------
At the time of writing, git-http-push cannot remotely create a GIT
repository. So we have to do that at the server side with git. Another
option would be to generate an empty repository at the client and copy
it to the server with WebDAV. But then you're probably the first to
try that out :)
Create the directory under the DocumentRoot of the directories served
by Apache. As an example we take /usr/local/apache2, but try "grep
DocumentRoot /where/ever/httpd.conf" to find your root:
$ cd /usr/local/apache/htdocs
$ mkdir my-new-repo.git
On Debian:
$ cd /var/www
$ mkdir my-new-repo.git
Initialize a bare repository
$ cd my-new-repo.git
$ git --bare init-db
Change the ownership to your web-server's credentials. Use "grep ^User
httpd.conf" and "grep ^Group httpd.conf" to find out:
$ chown -R www.www .
On Debian:
$ chown -R www-data.www-data .
If you do not know which user Apache runs as, you can alternatively do
a "chmod -R a+w .", inspect the files which are created later on, and
set the permissions appropriately.
Restart apache2, and check whether http://server/my-new-repo.git gives
a directory listing. If not, check whether apache started up
successfully.
Step 2: enable DAV on this repository
-------------------------------------
First make sure the dav_module is loaded. For this, insert in httpd.conf:
LoadModule dav_module libexec/httpd/libdav.so
AddModule mod_dav.c
Also make sure that this line exists which is the file used for
locking DAV operations:
DAVLockDB "/usr/local/apache2/temp/DAV.lock"
On Debian these steps can be performed with:
Enable the dav and dav_fs modules of apache:
$ a2enmod dav_fs
(just to be sure. dav_fs might be unneeded, I don't know)
$ a2enmod dav
The DAV lock is located in /etc/apache2/mods-available/dav_fs.conf:
DAVLockDB /var/lock/apache2/DAVLock
Of course, it can point somewhere else, but the string is actually just a
prefix in some Apache configurations, and therefore the _directory_ has to
be writable by the user Apache runs as.
Then, add something like this to your httpd.conf
<Location /my-new-repo.git>
DAV on
AuthType Basic
AuthName "Git"
AuthUserFile /usr/local/apache2/conf/passwd.git
Require valid-user
</Location>
On Debian:
Create (or add to) /etc/apache2/conf.d/git.conf :
<Location /my-new-repo.git>
DAV on
AuthType Basic
AuthName "Git"
AuthUserFile /etc/apache2/passwd.git
Require valid-user
</Location>
Debian automatically reads all files under /etc/apach2/conf.d.
The password file can be somewhere else, but it has to be readable by
Apache and preferably not readable by the world.
Create this file by
$ htpasswd -c /usr/local/apache2/conf/passwd.git <user>
On Debian:
$ htpasswd -c /etc/apache2/passwd.git <user>
You will be asked a password, and the file is created. Subsequent calls
to htpasswd should omit the '-c' option, since you want to append to the
existing file.
You need to restart Apache.
Now go to http://<username>@<servername>/my-new-repo.git in your
browser to check whether it asks for a password and accepts the right
password.
On Debian:
To test the WebDAV part, do:
$ apt-get install litmus
$ litmus http://<servername>/my-new-repo.git <username> <password>
Most tests should pass.
A command line tool to test WebDAV is cadaver.
If you're into Windows, from XP onwards Internet Explorer supports
WebDAV. For this, do Internet Explorer -> Open Location ->
http://<servername>/my-new-repo.git [x] Open as webfolder -> login .
Step 3: setup the client
------------------------
Make sure that you have HTTP support, i.e. your git was built with curl.
The easiest way to check is to look for the executable 'git-http-push'.
Then, add the following to your $HOME/.netrc (you can do without, but will be
asked to input your password a _lot_ of times):
machine <servername>
login <username>
password <password>
...and set permissions:
chmod 600 ~/.netrc
If you want to access the web-server by its IP, you have to type that in,
instead of the server name.
To check whether all is OK, do:
curl --netrc --location -v http://<username>@<servername>/my-new-repo.git/
...this should give a directory listing in HTML of /var/www/my-new-repo.git .
Now, add the remote in your existing repository which contains the project
you want to export:
$ git-repo-config remote.upload.url \
http://<username>@<servername>/my-new-repo.git/
It is important to put the last '/'; Without it, the server will send
a redirect which git-http-push does not (yet) understand, and git-http-push
will repeat the request infinitely.
Step 4: make the initial push
-----------------------------
From your client repository, do
$ git push upload master
This pushes branch 'master' (which is assumed to be the branch you
want to export) to repository called 'upload', which we previously
defined with git-repo-config.
Troubleshooting:
----------------
If git-http-push says
Error: no DAV locking support on remote repo http://...
then it means the web-server did not accept your authentication. Make sure
that the user name and password matches in httpd.conf, .netrc and the URL
you are uploading to.
If git-http-push shows you an error (22/502) when trying to MOVE a blob,
it means that your web-server somehow does not recognize its name in the
request; This can happen when you start Apache, but then disable the
network interface. A simple restart of Apache helps.
Errors like (22/502) are of format (curl error code/http error
code). So (22/404) means something like 'not found' at the server.
Reading /usr/local/apache2/logs/error_log is often helpful.
On Debian: Read /var/log/apache2/error.log instead.
Debian References: http://www.debian-administration.org/articles/285
Authors
Johannes Schindelin <Johannes.Schindelin@gmx.de>
Rutger Nijlunsing <git@wingding.demon.nl>

View File

@ -244,6 +244,7 @@ $ git ls-files --stage
$ git cat-file -t 513feba2
blob
$ git cat-file blob 513feba2
hello world!
hello world, again
------------------------------------------------

View File

@ -1,11 +1,19 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
DEF_VER=v1.4.GIT
DEF_VER=v1.4.2.GIT
LF='
'
# First try git-describe, then see if there is a version file
# (included in release tarballs), then default
if VN=$(git describe --abbrev=4 HEAD 2>/dev/null); then
if VN=$(git describe --abbrev=4 HEAD 2>/dev/null) &&
case "$VN" in
*$LF*) (exit 1) ;;
v[0-9]*) : happy ;;
esac
then
VN=$(echo "$VN" | sed -e 's/-/./g');
elif test -f version
then

View File

@ -24,6 +24,11 @@ all:
# 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).
#
# Define NO_C99_FORMAT if your formatted IO functions (printf/scanf et.al.)
# do not support the 'size specifiers' introduced by C99, namely ll, hh,
# j, z, t. (representing long long int, char, intmax_t, size_t, ptrdiff_t).
# some c compilers supported these specifiers prior to C99 as an extension.
#
# Define NO_STRCASESTR if you don't have strcasestr.
#
# Define NO_STRLCPY if you don't have strlcpy.
@ -173,14 +178,14 @@ PROGRAMS = \
git-hash-object$X git-index-pack$X git-local-fetch$X \
git-merge-base$X \
git-merge-index$X git-mktag$X git-mktree$X git-pack-objects$X git-patch-id$X \
git-peek-remote$X git-prune-packed$X git-receive-pack$X \
git-peek-remote$X git-receive-pack$X \
git-send-pack$X git-shell$X \
git-show-index$X git-ssh-fetch$X \
git-ssh-upload$X git-unpack-file$X \
git-unpack-objects$X git-update-server-info$X \
git-upload-pack$X git-verify-pack$X \
git-symbolic-ref$X \
git-name-rev$X git-pack-redundant$X git-repo-config$X git-var$X \
git-name-rev$X git-pack-redundant$X git-var$X \
git-describe$X git-merge-tree$X git-blame$X git-imap-send$X \
git-merge-recur$X
@ -193,7 +198,8 @@ 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-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-fmt-merge-msg$X git-prune$X git-mv$X
git-fmt-merge-msg$X git-prune$X git-mv$X git-prune-packed$X \
git-repo-config$X
# what 'all' will build and 'install' will install, in gitexecdir
ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS)
@ -250,7 +256,7 @@ BUILTIN_OBJS = \
builtin-diff-index.o builtin-diff-stages.o builtin-diff-tree.o \
builtin-cat-file.o builtin-mailsplit.o builtin-stripspace.o \
builtin-update-ref.o builtin-fmt-merge-msg.o builtin-prune.o \
builtin-mv.o
builtin-mv.o builtin-prune-packed.o builtin-repo-config.o
GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
LIBS = $(GITLIBS) -lz
@ -309,9 +315,9 @@ ifeq ($(uname_O),Cygwin)
NO_D_TYPE_IN_DIRENT = YesPlease
NO_D_INO_IN_DIRENT = YesPlease
NO_STRCASESTR = YesPlease
NO_STRLCPY = YesPlease
NO_SYMLINK_HEAD = YesPlease
NEEDS_LIBICONV = YesPlease
NO_C99_FORMAT = YesPlease
# There are conflicting reports about this.
# On some boxes NO_MMAP is needed, and not so elsewhere.
# Try uncommenting this if you see things break -- YMMV.
@ -433,6 +439,9 @@ endif
ifdef NO_D_INO_IN_DIRENT
ALL_CFLAGS += -DNO_D_INO_IN_DIRENT
endif
ifdef NO_C99_FORMAT
ALL_CFLAGS += -DNO_C99_FORMAT
endif
ifdef NO_SYMLINK_HEAD
ALL_CFLAGS += -DNO_SYMLINK_HEAD
endif
@ -718,7 +727,7 @@ install: all
$(INSTALL) -d -m755 '$(DESTDIR_SQ)$(gitexecdir_SQ)'
$(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexecdir_SQ)'
$(INSTALL) git$X gitk '$(DESTDIR_SQ)$(bindir_SQ)'
$(MAKE) -C templates install
$(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install
$(INSTALL) -d -m755 '$(DESTDIR_SQ)$(GIT_PYTHON_DIR_SQ)'
$(INSTALL) $(PYMODULES) '$(DESTDIR_SQ)$(GIT_PYTHON_DIR_SQ)'
if test 'z$(bindir_SQ)' != 'z$(gitexecdir_SQ)'; \

15
alloc.c
View File

@ -39,8 +39,21 @@ DEFINE_ALLOCATOR(tree)
DEFINE_ALLOCATOR(commit)
DEFINE_ALLOCATOR(tag)
#ifdef NO_C99_FORMAT
#define SZ_FMT "%u"
#else
#define SZ_FMT "%zu"
#endif
static void report(const char* name, unsigned int count, size_t size)
{
fprintf(stderr, "%10s: %8u (" SZ_FMT " kB)\n", name, count, size);
}
#undef SZ_FMT
#define REPORT(name) \
fprintf(stderr, "%10s: %8u (%zu kB)\n", #name, name##_allocs, name##_allocs*sizeof(struct name) >> 10)
report(#name, name##_allocs, name##_allocs*sizeof(struct name) >> 10)
void alloc_report(void)
{

View File

@ -20,7 +20,7 @@
#define DEBUG 0
static const char blame_usage[] = "[-c] [-l] [-t] [-S <revs-file>] [--] file [commit]\n"
static const char blame_usage[] = "git-blame [-c] [-l] [-t] [-S <revs-file>] [--] file [commit]\n"
" -c, --compatibility Use the same output mode as git-annotate (Default: off)\n"
" -l, --long Show long commit SHA1 (Default: off)\n"
" -t, --time Show raw timestamp (Default: off)\n"

View File

@ -93,9 +93,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
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");
newfd = hold_lock_file_for_update(&lock_file, get_index_file(), 1);
if (read_cache() < 0)
die("index file corrupt");
@ -117,7 +115,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
verbose = 1;
continue;
}
die(builtin_add_usage);
usage(builtin_add_usage);
}
pathspec = get_pathspec(prefix, argv + i);

View File

@ -1698,6 +1698,12 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *
desc.buffer = buf;
if (apply_fragments(&desc, patch) < 0)
return -1;
/* NUL terminate the result */
if (desc.alloc <= desc.size)
desc.buffer = xrealloc(desc.buffer, desc.size + 1);
desc.buffer[desc.size] = 0;
patch->result = desc.buffer;
patch->resultsize = desc.size;
@ -2040,6 +2046,9 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,
int fd;
if (S_ISLNK(mode))
/* Although buf:size is counted string, it also is NUL
* terminated.
*/
return symlink(buf, path);
fd = open(path, O_CREAT | O_EXCL | O_WRONLY, (mode & 0100) ? 0777 : 0666);
if (fd < 0)
@ -2225,12 +2234,9 @@ static int apply_patch(int fd, const char *filename,
apply = 0;
write_index = check_index && apply;
if (write_index && newfd < 0) {
if (write_index && newfd < 0)
newfd = hold_lock_file_for_update(&lock_file,
get_index_file());
if (newfd < 0)
die("unable to create new index file");
}
get_index_file(), 1);
if (check_index) {
if (read_cache() < 0)
die("unable to read index file");

View File

@ -9,6 +9,6 @@
int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
{
if (argc != 2)
usage("git check-ref-format refname");
usage("git-check-ref-format refname");
return !!check_ref_format(argv[1]);
}

View File

@ -23,7 +23,7 @@ struct blobinfo {
};
static const char builtin_diff_usage[] =
"diff <options> <rev>{0,2} -- <path>*";
"git-diff <options> <rev>{0,2} -- <path>*";
static int builtin_diff_files(struct rev_info *revs,
int argc, const char **argv)
@ -125,9 +125,6 @@ static int builtin_diff_blobs(struct rev_info *revs,
int argc, const char **argv,
struct blobinfo *blob)
{
/* Blobs: the arguments are reversed when setup_revisions()
* picked them up.
*/
unsigned mode = canon_mode(S_IFREG | 0644);
if (argc > 1)
@ -135,8 +132,8 @@ static int builtin_diff_blobs(struct rev_info *revs,
stuff_change(&revs->diffopt,
mode, mode,
blob[1].sha1, blob[0].sha1,
blob[0].name, blob[0].name);
blob[0].sha1, blob[1].sha1,
blob[0].name, blob[1].name);
diffcore_std(&revs->diffopt);
diff_flush(&revs->diffopt);
return 0;
@ -256,7 +253,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
argc = setup_revisions(argc, argv, &rev, NULL);
if (!rev.diffopt.output_format) {
rev.diffopt.output_format = DIFF_FORMAT_PATCH;
diff_setup_done(&rev.diffopt);
if (diff_setup_done(&rev.diffopt) < 0)
die("diff_setup_done failed");
}
/* Do we have --cached and not have a pending object, then
@ -351,6 +349,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
* A and B. We have ent[0] == merge-base, ent[1] == A,
* and ent[2] == B. Show diff between the base and B.
*/
ent[1] = ent[2];
return builtin_diff_tree(&rev, argc, argv, ent);
}
else

View File

@ -1,3 +1,4 @@
#include "builtin.h"
#include "cache.h"
#include "commit.h"
#include "diff.h"
@ -242,7 +243,7 @@ static void shortlog(const char *name, unsigned char *sha1,
free_list(&subjects);
}
int cmd_fmt_merge_msg(int argc, char **argv, const char *prefix)
int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
{
int limit = 20, i = 0;
char line[1024];

View File

@ -410,8 +410,10 @@ static int fixmatch(const char *pattern, char *line, regmatch_t *match)
static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol, char *eol)
{
int hit = 0;
int at_true_bol = 1;
regmatch_t pmatch[10];
again:
if (!opt->fixed) {
regex_t *exp = &p->regexp;
hit = !regexec(exp, bol, ARRAY_SIZE(pmatch),
@ -422,22 +424,35 @@ static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol
}
if (hit && opt->word_regexp) {
/* Match beginning must be either
* beginning of the line, or at word
* boundary (i.e. the last char must
* not be alnum or underscore).
*/
if ((pmatch[0].rm_so < 0) ||
(eol - bol) <= pmatch[0].rm_so ||
(pmatch[0].rm_eo < 0) ||
(eol - bol) < pmatch[0].rm_eo)
die("regexp returned nonsense");
if (pmatch[0].rm_so != 0 &&
word_char(bol[pmatch[0].rm_so-1]))
hit = 0;
if (pmatch[0].rm_eo != (eol-bol) &&
word_char(bol[pmatch[0].rm_eo]))
/* Match beginning must be either beginning of the
* line, or at word boundary (i.e. the last char must
* not be a word char). Similarly, match end must be
* either end of the line, or at word boundary
* (i.e. the next char must not be a word char).
*/
if ( ((pmatch[0].rm_so == 0 && at_true_bol) ||
!word_char(bol[pmatch[0].rm_so-1])) &&
((pmatch[0].rm_eo == (eol-bol)) ||
!word_char(bol[pmatch[0].rm_eo])) )
;
else
hit = 0;
if (!hit && pmatch[0].rm_so + bol + 1 < eol) {
/* There could be more than one match on the
* line, and the first match might not be
* strict word match. But later ones could be!
*/
bol = pmatch[0].rm_so + bol + 1;
at_true_bol = 0;
goto again;
}
}
return hit;
}

View File

@ -9,8 +9,6 @@
#include "exec_cmd.h"
#include "common-cmds.h"
static const char git_usage[] =
"Usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--help] COMMAND [ ARGS ]";
/* most GUI terminals set COLUMNS (although some don't export it) */
static int term_columns(void)
@ -142,7 +140,7 @@ static void list_commands(const char *exec_path, const char *pattern)
continue;
entlen = strlen(de->d_name);
if (4 < entlen && !strcmp(de->d_name + entlen - 4, ".exe"))
if (has_extension(de->d_name, ".exe"))
entlen -= 4;
if (longest < entlen)
@ -178,31 +176,6 @@ static void list_common_cmds_help(void)
puts("(use 'git help -a' to get a list of all installed git commands)");
}
void cmd_usage(int show_all, const char *exec_path, const char *fmt, ...)
{
if (fmt) {
va_list ap;
va_start(ap, fmt);
printf("git: ");
vprintf(fmt, ap);
va_end(ap);
putchar('\n');
}
else
puts(git_usage);
if (exec_path) {
putchar('\n');
if (show_all)
list_commands(exec_path, "git-*");
else
list_common_cmds_help();
}
exit(1);
}
static void show_man_page(const char *git_cmd)
{
const char *page;
@ -221,6 +194,13 @@ static void show_man_page(const char *git_cmd)
execlp("man", "man", page, NULL);
}
void help_unknown_cmd(const char *cmd)
{
printf("git: '%s' is not a git-command\n\n", cmd);
list_common_cmds_help();
exit(1);
}
int cmd_version(int argc, const char **argv, const char *prefix)
{
printf("git version %s\n", git_version_string);
@ -230,12 +210,24 @@ int cmd_version(int argc, const char **argv, const char *prefix)
int cmd_help(int argc, const char **argv, const char *prefix)
{
const char *help_cmd = argc > 1 ? argv[1] : NULL;
if (!help_cmd)
cmd_usage(0, git_exec_path(), NULL);
else if (!strcmp(help_cmd, "--all") || !strcmp(help_cmd, "-a"))
cmd_usage(1, git_exec_path(), NULL);
const char *exec_path = git_exec_path();
if (!help_cmd) {
printf("usage: %s\n\n", git_usage_string);
list_common_cmds_help();
exit(1);
}
else if (!strcmp(help_cmd, "--all") || !strcmp(help_cmd, "-a")) {
printf("usage: %s\n\n", git_usage_string);
if(exec_path)
list_commands(exec_path, "git-*");
exit(1);
}
else
show_man_page(help_cmd);
return 0;
}

View File

@ -267,7 +267,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
else if (!strncmp(arg, "--shared=", 9))
shared_repository = git_config_perm("arg", arg+9);
else
die(init_db_usage);
usage(init_db_usage);
}
/*

View File

@ -34,7 +34,6 @@ static int cmd_log_walk(struct rev_info *rev)
struct commit *commit;
prepare_revision_walk(rev);
setup_pager();
while ((commit = get_revision(rev)) != NULL) {
log_tree_commit(rev, commit);
free(commit->buffer);
@ -258,6 +257,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
char message_id[1024];
char ref_message_id[1024];
setup_ident();
git_config(git_format_config);
init_revisions(&rev, prefix);
rev.commit_format = CMIT_FMT_EMAIL;
@ -307,7 +307,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
!strcmp(argv[i], "-s")) {
const char *committer;
const char *endpos;
setup_ident();
committer = git_committer_info(1);
endpos = strchr(committer, '>');
if (!endpos)

View File

@ -24,7 +24,6 @@ static int show_valid_bit = 0;
static int line_terminator = '\n';
static int prefix_len = 0, prefix_offset = 0;
static const char *prefix = NULL;
static const char **pathspec = NULL;
static int error_unmatch = 0;
static char *ps_matched = NULL;
@ -207,7 +206,7 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce)
}
}
static void show_files(struct dir_struct *dir)
static void show_files(struct dir_struct *dir, const char *prefix)
{
int i;
@ -253,7 +252,7 @@ static void show_files(struct dir_struct *dir)
/*
* Prune the index to only contain stuff starting with "prefix"
*/
static void prune_cache(void)
static void prune_cache(const char *prefix)
{
int pos = cache_name_pos(prefix, prefix_len);
unsigned int first, last;
@ -276,7 +275,7 @@ static void prune_cache(void)
active_nr = last;
}
static void verify_pathspec(void)
static const char *verify_pathspec(const char *prefix)
{
const char **p, *n, *prev;
char *real_prefix;
@ -313,7 +312,7 @@ static void verify_pathspec(void)
memcpy(real_prefix, prev, max);
real_prefix[max] = 0;
}
prefix = real_prefix;
return real_prefix;
}
static const char ls_files_usage[] =
@ -453,7 +452,7 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
/* Verify that the pathspec matches the prefix */
if (pathspec)
verify_pathspec();
prefix = verify_pathspec(prefix);
/* Treat unmatching pathspec elements as errors */
if (pathspec && error_unmatch) {
@ -476,8 +475,8 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
read_cache();
if (prefix)
prune_cache();
show_files(&dir);
prune_cache(prefix);
show_files(&dir, prefix);
if (ps_matched) {
/* We need to make sure all pathspec matched otherwise

View File

@ -48,7 +48,8 @@ static const char *add_slash(const char *path)
if (path[len - 1] != '/') {
char *with_slash = xmalloc(len + 2);
memcpy(with_slash, path, len);
strcat(with_slash + len, "/");
with_slash[len++] = '/';
with_slash[len] = 0;
return with_slash;
}
return path;
@ -71,10 +72,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
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");
newfd = hold_lock_file_for_update(&lock_file, get_index_file(), 1);
if (read_cache() < 0)
die("index file corrupt");
@ -99,7 +97,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
ignore_errors = 1;
continue;
}
die(builtin_mv_usage);
usage(builtin_mv_usage);
}
count = argc - i - 1;
if (count < 1)

View File

@ -1,3 +1,4 @@
#include "builtin.h"
#include "cache.h"
static const char prune_packed_usage[] =
@ -54,12 +55,10 @@ static void prune_packed_objects(void)
}
}
int main(int argc, char **argv)
int cmd_prune_packed(int argc, const char **argv, const char *prefix)
{
int i;
setup_git_directory();
for (i = 1; i < argc; i++) {
const char *arg = argv[i];

View File

@ -10,7 +10,7 @@
#include "builtin.h"
#include "cache-tree.h"
static const char prune_usage[] = "git prune [-n]";
static const char prune_usage[] = "git-prune [-n]";
static int show_only = 0;
static struct rev_info revs;

View File

@ -8,7 +8,7 @@
#define MAX_URI (16)
static const char push_usage[] = "git push [--all] [--tags] [--force] <repository> [<refspec>...]";
static const char push_usage[] = "git-push [--all] [--tags] [-f | --force] <repository> [<refspec>...]";
static int all = 0, tags = 0, force = 0, thin = 1;
static const char *execute = NULL;
@ -291,7 +291,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
tags = 1;
continue;
}
if (!strcmp(arg, "--force")) {
if (!strcmp(arg, "--force") || !strcmp(arg, "-f")) {
force = 1;
continue;
}

View File

@ -88,7 +88,7 @@ static const char read_tree_usage[] = "git-read-tree (<sha> | [[-m [--aggressive
static struct lock_file lock_file;
int cmd_read_tree(int argc, const char **argv, const char *prefix)
int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
{
int i, newfd, stage = 0;
unsigned char sha1[20];
@ -100,9 +100,7 @@ int cmd_read_tree(int argc, const char **argv, const char *prefix)
setup_git_directory();
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");
newfd = hold_lock_file_for_update(&lock_file, get_index_file(), 1);
git_config(git_default_config);

View File

@ -1,3 +1,4 @@
#include "builtin.h"
#include "cache.h"
#include <regex.h>
@ -128,7 +129,7 @@ free_strings:
return ret;
}
int main(int argc, const char **argv)
int cmd_repo_config(int argc, const char **argv, const char *prefix)
{
int nongit = 0;
setup_git_directory_gently(&nongit);

View File

@ -52,9 +52,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
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");
newfd = hold_lock_file_for_update(&lock_file, get_index_file(), 1);
if (read_cache() < 0)
die("index file corrupt");
@ -80,7 +78,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
force = 1;
continue;
}
die(builtin_rm_usage);
usage(builtin_rm_usage);
}
if (argc <= i)
usage(builtin_rm_usage);
@ -115,7 +113,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
printf("rm '%s'\n", path);
if (remove_file_from_cache(path))
die("git rm: unable to remove %s", path);
die("git-rm: unable to remove %s", path);
cache_tree_invalidate_path(active_cache_tree, path);
}
@ -139,7 +137,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
continue;
}
if (!removed)
die("git rm: %s: %s", path, strerror(errno));
die("git-rm: %s: %s", path, strerror(errno));
}
}

View File

@ -314,6 +314,7 @@ static int generate_tar(int argc, const char **argv, const char *prefix)
struct commit *commit;
struct tree_desc tree;
struct strbuf current_path;
void *buffer;
current_path.buf = xmalloc(PATH_MAX);
current_path.alloc = PATH_MAX;
@ -341,8 +342,8 @@ static int generate_tar(int argc, const char **argv, const char *prefix)
} else
archive_time = time(NULL);
tree.buf = read_object_with_reference(sha1, tree_type, &tree.size,
tree_sha1);
tree.buf = buffer = read_object_with_reference(sha1, tree_type,
&tree.size, tree_sha1);
if (!tree.buf)
die("not a reference to a tag, commit or tree object: %s",
sha1_to_hex(sha1));
@ -351,6 +352,7 @@ static int generate_tar(int argc, const char **argv, const char *prefix)
write_entry(tree_sha1, &current_path, 040777, NULL, 0);
traverse_tree(&tree, &current_path);
write_trailer();
free(buffer);
free(current_path.buf);
return 0;
}

View File

@ -491,9 +491,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
/* We can't free this memory, it becomes part of a linked list parsed atexit() */
lock_file = xcalloc(1, sizeof(struct lock_file));
newfd = hold_lock_file_for_update(lock_file, get_index_file());
if (newfd < 0)
die("unable to create new cachefile");
newfd = hold_lock_file_for_update(lock_file, get_index_file(), 1);
entries = read_cache();
if (entries < 0)

View File

@ -18,7 +18,7 @@ int write_tree(unsigned char *sha1, int missing_ok, const char *prefix)
/* We can't free this memory, it becomes part of a linked list parsed atexit() */
struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
newfd = hold_lock_file_for_update(lock_file, get_index_file());
newfd = hold_lock_file_for_update(lock_file, get_index_file(), 0);
entries = read_cache();
if (entries < 0)
@ -73,7 +73,7 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
else if (!strncmp(arg, "--prefix=", 9))
prefix = arg + 9;
else
die(write_tree_usage);
usage(write_tree_usage);
argc--; argv++;
}

View File

@ -2,18 +2,12 @@
#define BUILTIN_H
#include <stdio.h>
#ifndef PATH_MAX
# define PATH_MAX 4096
#endif
#include <limits.h>
extern const char git_version_string[];
extern const char git_usage_string[];
void cmd_usage(int show_all, const char *exec_path, const char *fmt, ...)
#ifdef __GNUC__
__attribute__((__format__(__printf__, 3, 4), __noreturn__))
#endif
;
extern void help_unknown_cmd(const char *cmd);
extern int cmd_help(int argc, const char **argv, const char *prefix);
extern int cmd_version(int argc, const char **argv, const char *prefix);
@ -26,6 +20,7 @@ extern int cmd_format_patch(int argc, const char **argv, const char *prefix);
extern int cmd_count_objects(int argc, const char **argv, const char *prefix);
extern int cmd_prune(int argc, const char **argv, const char *prefix);
extern int cmd_prune_packed(int argc, const char **argv, const char *prefix);
extern int cmd_push(int argc, const char **argv, const char *prefix);
extern int cmd_grep(int argc, const char **argv, const char *prefix);
@ -53,6 +48,7 @@ extern int cmd_update_index(int argc, const char **argv, const char *prefix);
extern int cmd_update_ref(int argc, const char **argv, const char *prefix);
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_repo_config(int argc, const char **argv, const char *prefix);
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);

View File

@ -176,7 +176,7 @@ struct lock_file {
struct lock_file *next;
char filename[PATH_MAX];
};
extern int hold_lock_file_for_update(struct lock_file *, const char *path);
extern int hold_lock_file_for_update(struct lock_file *, const char *path, int);
extern int commit_lock_file(struct lock_file *);
extern void rollback_lock_file(struct lock_file *);
@ -387,6 +387,7 @@ extern int receive_keep_pack(int fd[2], const char *me, int quiet, int);
/* pager.c */
extern void setup_pager(void);
extern int pager_in_use;
extern int pager_use_color;
/* base85 */
int decode_85(char *dst, char *line, int linelen);

View File

@ -206,7 +206,7 @@ int main(int argc, char **argv)
state.refresh_cache = 1;
if (newfd < 0)
newfd = hold_lock_file_for_update
(&lock_file, get_index_file());
(&lock_file, get_index_file(), 1);
if (newfd < 0)
die("cannot open index.lock file.");
continue;

View File

@ -497,11 +497,17 @@ static void show_parent_lno(struct sline *sline, unsigned long l0, unsigned long
printf(" -%lu,%lu", l0, l1-l0);
}
static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent)
static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,
int use_color)
{
unsigned long mark = (1UL<<num_parent);
int i;
unsigned long lno = 0;
const char *c_frag = diff_get_color(use_color, DIFF_FRAGINFO);
const char *c_new = diff_get_color(use_color, DIFF_FILE_NEW);
const char *c_old = diff_get_color(use_color, DIFF_FILE_OLD);
const char *c_plain = diff_get_color(use_color, DIFF_PLAIN);
const char *c_reset = diff_get_color(use_color, DIFF_RESET);
if (!cnt)
return; /* result deleted */
@ -522,12 +528,13 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent)
rlines = hunk_end - lno;
if (cnt < hunk_end)
rlines--; /* pointing at the last delete hunk */
fputs(c_frag, stdout);
for (i = 0; i <= num_parent; i++) putchar(combine_marker);
for (i = 0; i < num_parent; i++)
show_parent_lno(sline, lno, hunk_end, i);
printf(" +%lu,%lu ", lno+1, rlines);
for (i = 0; i <= num_parent; i++) putchar(combine_marker);
putchar('\n');
printf("%s\n", c_reset);
while (lno < hunk_end) {
struct lline *ll;
int j;
@ -535,18 +542,23 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent)
sl = &sline[lno++];
ll = sl->lost_head;
while (ll) {
fputs(c_old, stdout);
for (j = 0; j < num_parent; j++) {
if (ll->parent_map & (1UL<<j))
putchar('-');
else
putchar(' ');
}
puts(ll->line);
printf("%s%s\n", ll->line, c_reset);
ll = ll->next;
}
if (cnt < lno)
break;
p_mask = 1;
if (!(sl->flag & (mark-1)))
fputs(c_plain, stdout);
else
fputs(c_new, stdout);
for (j = 0; j < num_parent; j++) {
if (p_mask & sl->flag)
putchar('+');
@ -554,7 +566,7 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent)
putchar(' ');
p_mask <<= 1;
}
printf("%.*s\n", sl->len, sl->bol);
printf("%.*s%s\n", sl->len, sl->bol, c_reset);
}
}
}
@ -586,14 +598,15 @@ static void reuse_combine_diff(struct sline *sline, unsigned long cnt,
sline->p_lno[i] = sline->p_lno[j];
}
static void dump_quoted_path(const char *prefix, const char *path)
static void dump_quoted_path(const char *prefix, const char *path,
const char *c_meta, const char *c_reset)
{
fputs(prefix, stdout);
printf("%s%s", c_meta, prefix);
if (quote_c_style(path, NULL, NULL, 0))
quote_c_style(path, NULL, stdout, 0);
else
printf("%s", path);
putchar('\n');
printf("%s\n", c_reset);
}
static int show_patch_diff(struct combine_diff_path *elem, int num_parent,
@ -699,18 +712,22 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent,
if (show_hunks || mode_differs || working_tree_file) {
const char *abb;
int use_color = opt->color_diff;
const char *c_meta = diff_get_color(use_color, DIFF_METAINFO);
const char *c_reset = diff_get_color(use_color, DIFF_RESET);
if (rev->loginfo)
show_log(rev, opt->msg_sep);
dump_quoted_path(dense ? "diff --cc " : "diff --combined ", elem->path);
printf("index ");
dump_quoted_path(dense ? "diff --cc " : "diff --combined ",
elem->path, c_meta, c_reset);
printf("%sindex ", c_meta);
for (i = 0; i < num_parent; i++) {
abb = find_unique_abbrev(elem->parent[i].sha1,
abbrev);
printf("%s%s", i ? "," : "", abb);
}
abb = find_unique_abbrev(elem->sha1, abbrev);
printf("..%s\n", abb);
printf("..%s%s\n", abb, c_reset);
if (mode_differs) {
int added = !!elem->mode;
@ -719,10 +736,11 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent,
DIFF_STATUS_ADDED)
added = 0;
if (added)
printf("new file mode %06o", elem->mode);
printf("%snew file mode %06o",
c_meta, elem->mode);
else {
if (!elem->mode)
printf("deleted file ");
printf("%sdeleted file ", c_meta);
printf("mode ");
for (i = 0; i < num_parent; i++) {
printf("%s%06o", i ? "," : "",
@ -731,11 +749,11 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent,
if (elem->mode)
printf("..%06o", elem->mode);
}
putchar('\n');
printf("%s\n", c_reset);
}
dump_quoted_path("--- a/", elem->path);
dump_quoted_path("+++ b/", elem->path);
dump_sline(sline, cnt, num_parent);
dump_quoted_path("--- a/", elem->path, c_meta, c_reset);
dump_quoted_path("+++ b/", elem->path, c_meta, c_reset);
dump_sline(sline, cnt, num_parent, opt->color_diff);
}
free(result);

View File

@ -309,6 +309,11 @@ int git_default_config(const char *var, const char *value)
return 0;
}
if (!strcmp(var, "pager.color")) {
pager_use_color = git_config_bool(var,value);
return 0;
}
/* Add other config variables here and to Documentation/config.txt. */
return 0;
}

View File

@ -2,7 +2,7 @@
# 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_INIT([git], [1.4.2], [git@vger.kernel.org])
AC_CONFIG_SRCDIR([git.c])

View File

@ -1,5 +1,6 @@
#define _XOPEN_SOURCE 500 /* glibc2 and AIX 5.3L need this */
#define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */
#define _GNU_SOURCE
#include <time.h>
#include "cache.h"
#include "blob.h"

14
diff.c
View File

@ -175,7 +175,7 @@ int git_diff_ui_config(const char *var, const char *value)
diff_use_color_default = 1; /* bool */
else if (!strcasecmp(value, "auto")) {
diff_use_color_default = 0;
if (isatty(1) || pager_in_use) {
if (isatty(1) || (pager_in_use && pager_use_color)) {
char *term = getenv("TERM");
if (term && strcmp(term, "dumb"))
diff_use_color_default = 1;
@ -1515,10 +1515,8 @@ void diff_setup(struct diff_options *options)
int diff_setup_done(struct diff_options *options)
{
if ((options->find_copies_harder &&
options->detect_rename != DIFF_DETECT_COPY) ||
(0 <= options->rename_limit && !options->detect_rename))
return -1;
if (options->find_copies_harder)
options->detect_rename = DIFF_DETECT_COPY;
if (options->output_format & (DIFF_FORMAT_NAME |
DIFF_FORMAT_NAME_STATUS |
@ -1786,13 +1784,9 @@ struct diff_filepair *diff_queue(struct diff_queue_struct *queue,
struct diff_filespec *one,
struct diff_filespec *two)
{
struct diff_filepair *dp = xmalloc(sizeof(*dp));
struct diff_filepair *dp = xcalloc(1, sizeof(*dp));
dp->one = one;
dp->two = two;
dp->score = 0;
dp->status = 0;
dp->source_stays = 0;
dp->broken_pair = 0;
if (queue)
diff_q(queue, dp);
return dp;

View File

@ -205,6 +205,7 @@ static void record_rename_pair(int dst_index, int src_index, int score)
fill_filespec(two, dst->sha1, dst->mode);
dp = diff_queue(NULL, one, two);
dp->renamed_pair = 1;
if (!strcmp(src->path, dst->path))
dp->score = rename_src[src_index].score;
else

View File

@ -53,11 +53,12 @@ struct diff_filepair {
char status; /* M C R N D U (see Documentation/diff-format.txt) */
unsigned source_stays : 1; /* all of R/C are copies */
unsigned broken_pair : 1;
unsigned renamed_pair : 1;
};
#define DIFF_PAIR_UNMERGED(p) \
(!DIFF_FILE_VALID((p)->one) && !DIFF_FILE_VALID((p)->two))
#define DIFF_PAIR_RENAME(p) (strcmp((p)->one->path, (p)->two->path))
#define DIFF_PAIR_RENAME(p) ((p)->renamed_pair)
#define DIFF_PAIR_BROKEN(p) \
( (!DIFF_FILE_VALID((p)->one) != !DIFF_FILE_VALID((p)->two)) && \

View File

@ -23,6 +23,7 @@ int shared_repository = PERM_UMASK;
const char *apply_default_whitespace = NULL;
int zlib_compression_level = Z_DEFAULT_COMPRESSION;
int pager_in_use;
int pager_use_color = 1;
static char *git_dir, *git_object_dir, *git_index_file, *git_refs_dir,
*git_graft_file;

View File

@ -129,10 +129,12 @@ static pid_t setup_sideband(int sideband, const char *me, int fd[2], int xd[2])
len--;
switch (buf[0] & 0xFF) {
case 3:
safe_write(2, "remote: ", 8);
safe_write(2, buf+1, len);
fprintf(stderr, "\n");
safe_write(2, "\n", 1);
exit(1);
case 2:
safe_write(2, "remote: ", 8);
safe_write(2, buf+1, len);
continue;
case 1:

View File

@ -45,6 +45,12 @@ go_next () {
this=$next
}
cannot_fallback () {
echo "$1"
echo "Cannot fall back to three-way merge."
exit 1
}
fall_back_3way () {
O_OBJECT=`cd "$GIT_OBJECT_DIRECTORY" && pwd`
@ -52,19 +58,23 @@ fall_back_3way () {
mkdir "$dotest/patch-merge-tmp-dir"
# First see if the patch records the index info that we can use.
if git-apply -z --index-info "$dotest/patch" \
>"$dotest/patch-merge-index-info" 2>/dev/null &&
GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
git-update-index -z --index-info <"$dotest/patch-merge-index-info" &&
GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
git-write-tree >"$dotest/patch-merge-base+" &&
# index has the base tree now.
GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
git-apply -z --index-info "$dotest/patch" \
>"$dotest/patch-merge-index-info" &&
GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
git-update-index -z --index-info <"$dotest/patch-merge-index-info" &&
GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
git-write-tree >"$dotest/patch-merge-base+" ||
cannot_fallback "Patch does not record usable index information."
echo Using index info to reconstruct a base tree...
if GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
git-apply $binary --cached <"$dotest/patch"
then
echo Using index info to reconstruct a base tree...
mv "$dotest/patch-merge-base+" "$dotest/patch-merge-base"
mv "$dotest/patch-merge-tmp-index" "$dotest/patch-merge-index"
else
cannot_fallback "Did you hand edit your patch?
It does not apply to blobs recorded in its index."
fi
test -f "$dotest/patch-merge-index" &&

View File

@ -147,7 +147,7 @@ sub init_claim {
sub handle_rev {
my $i = 0;
my $revseen = 0;
my %seen;
while (my $rev = shift @revqueue) {
next if $seen{$rev}++;
@ -247,22 +247,129 @@ sub git_find_parent {
return $parent;
}
sub git_find_all_parents {
my ($rev) = @_;
my $revparent = open_pipe("git-rev-list","--remove-empty", "--parents","--max-count=1","$rev")
or die "Failed to open git-rev-list to find a single parent: $!";
my $parentline = <$revparent>;
chomp $parentline;
my ($origrev, @parents) = split m/\s+/, $parentline;
close($revparent);
return @parents;
}
sub git_merge_base {
my ($rev1, $rev2) = @_;
my $mb = open_pipe("git-merge-base", $rev1, $rev2)
or die "Failed to open git-merge-base: $!";
my $base = <$mb>;
chomp $base;
close($mb);
return $base;
}
# Construct a set of pseudo parents that are in the same order,
# and the same quantity as the real parents,
# but whose SHA1s are as similar to the logical parents
# as possible.
sub get_pseudo_parents {
my ($all, $fake) = @_;
my @all = @$all;
my @fake = @$fake;
my @pseudo;
my %fake = map {$_ => 1} @fake;
my %seenfake;
my $fakeidx = 0;
foreach my $p (@all) {
if (exists $fake{$p}) {
if ($fake[$fakeidx] ne $p) {
die sprintf("parent mismatch: %s != %s\nall:%s\nfake:%s\n",
$fake[$fakeidx], $p,
join(", ", @all),
join(", ", @fake),
);
}
push @pseudo, $p;
$fakeidx++;
$seenfake{$p}++;
} else {
my $base = git_merge_base($fake[$fakeidx], $p);
if ($base ne $fake[$fakeidx]) {
die sprintf("Result of merge-base doesn't match fake: %s,%s != %s\n",
$fake[$fakeidx], $p, $base);
}
# The details of how we parse the diffs
# mean that we cannot have a duplicate
# revision in the list, so if we've already
# seen the revision we would normally add, just use
# the actual revision.
if ($seenfake{$base}) {
push @pseudo, $p;
} else {
push @pseudo, $base;
$seenfake{$base}++;
}
}
}
return @pseudo;
}
# Get a diff between the current revision and a parent.
# Record the commit information that results.
sub git_diff_parse {
my ($parents, $rev, %revinfo) = @_;
my @pseudo_parents;
my @command = ("git-diff-tree");
my $revision_spec;
if (scalar @$parents == 1) {
$revision_spec = join("..", $parents->[0], $rev);
@pseudo_parents = @$parents;
} else {
my @all_parents = git_find_all_parents($rev);
if (@all_parents != @$parents) {
@pseudo_parents = get_pseudo_parents(\@all_parents, $parents);
} else {
@pseudo_parents = @$parents;
}
$revision_spec = $rev;
push @command, "-c";
}
my @filenames = ( $revs{$rev}{'filename'} );
foreach my $parent (@$parents) {
push @filenames, $revs{$parent}{'filename'};
}
my $diff = open_pipe("git-diff-tree","-M","-p","-c",$rev,"--",
@filenames )
push @command, "-p", "-M", $revision_spec, "--", @filenames;
my $diff = open_pipe( @command )
or die "Failed to call git-diff for annotation: $!";
_git_diff_parse($diff, $parents, $rev, %revinfo);
_git_diff_parse($diff, \@pseudo_parents, $rev, %revinfo);
close($diff);
}
@ -283,6 +390,7 @@ sub _git_diff_parse {
$diff_header_regexp .= "@" x @$parents;
$diff_header_regexp .= ' -\d+,\d+' x @$parents;
$diff_header_regexp .= ' \+(\d+),\d+';
$diff_header_regexp .= " " . ("@" x @$parents);
my %claim_regexps;
my $allparentplus = '^' . '\\+' x @$parents . '(.*)$';
@ -311,13 +419,13 @@ sub _git_diff_parse {
DIFF:
while(<$diff>) {
chomp;
#printf("%d:%s:\n", $gotheader, $_);
if (m/$diff_header_regexp/) {
$remstart = $1 - 1;
# (0-based arrays)
$gotheader = 1;
printf("Copying from %d to %d\n", $ri, $remstart);
foreach my $parent (@$parents) {
for (my $i = $ri; $i < $remstart; $i++) {
$plines{$parent}[$pi{$parent}++] = $slines->[$i];
@ -392,10 +500,17 @@ sub _git_diff_parse {
printf("parent %s is on line %d\n", $parent, $pi{$parent});
}
my @context;
for (my $i = -2; $i < 2; $i++) {
push @context, get_line($slines, $ri + $i);
}
my $context = join("\n", @context);
my $justline = substr($_, scalar @$parents);
die sprintf("Line %d, does not match:\n|%s|\n|%s|\n%s\n",
$ri,
substr($_,scalar @$parents),
get_line($slines,$ri), $rev);
$justline,
$context);
}
foreach my $parent (@$parents) {
$plines{$parent}[$pi{$parent}++] = $slines->[$ri];

View File

@ -67,6 +67,10 @@ while [ "$#" != "0" ]; do
set x "$arg" "$@"
shift
fi
case "$1" in
--)
shift ;;
esac
break
;;
esac

View File

@ -205,7 +205,7 @@ dir="$2"
[ -e "$dir" ] && echo "$dir already exists." && usage
mkdir -p "$dir" &&
D=$(cd "$dir" && pwd) &&
trap 'err=$?; cd ..; rm -r "$D"; exit $err' 0
trap 'err=$?; cd ..; rm -rf "$D"; exit $err' 0
case "$bare" in
yes)
GIT_DIR="$D" ;;
@ -298,7 +298,7 @@ yes,yes)
fi
git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1
;;
http://*)
https://*|http://*)
if test -z "@@NO_CURL@@"
then
clone_dumb_http "$repo" "$D"
@ -324,7 +324,8 @@ test -d "$GIT_DIR/refs/reference-tmp" && rm -fr "$GIT_DIR/refs/reference-tmp"
if test -f "$GIT_DIR/CLONE_HEAD"
then
# Read git-fetch-pack -k output and store the remote branches.
@@PERL@@ -e "$copy_refs" "$GIT_DIR" "$use_separate_remote" "$origin"
@@PERL@@ -e "$copy_refs" "$GIT_DIR" "$use_separate_remote" "$origin" ||
exit
fi
cd "$D" || exit

View File

@ -91,6 +91,9 @@ static inline void *xmalloc(size_t size)
ret = malloc(1);
if (!ret)
die("Out of memory, malloc failed");
#ifdef XMALLOC_POISON
memset(ret, 0xA5, size);
#endif
return ret;
}
@ -136,6 +139,13 @@ static inline ssize_t xwrite(int fd, const void *buf, size_t len)
}
}
static inline int has_extension(const char *filename, const char *ext)
{
size_t len = strlen(filename);
size_t extlen = strlen(ext);
return len > extlen && !memcmp(filename + len - extlen, ext, extlen);
}
/* Sane ctype - no locale, and works with signed chars */
#undef isspace
#undef isdigit

View File

@ -1,87 +0,0 @@
#!/bin/sh
USAGE='[--all] [--tags] [--force] <repository> [<refspec>...]'
. git-sh-setup
# Parse out parameters and then stop at remote, so that we can
# translate it using .git/branches information
has_all=
has_force=
has_exec=
has_thin=--thin
remote=
do_tags=
while case "$#" in 0) break ;; esac
do
case "$1" in
--all)
has_all=--all ;;
--tags)
do_tags=yes ;;
--force)
has_force=--force ;;
--exec=*)
has_exec="$1" ;;
--thin)
;; # noop
--no-thin)
has_thin= ;;
-*)
usage ;;
*)
set x "$@"
shift
break ;;
esac
shift
done
case "$#" in
0)
echo "Where would you want to push today?"
usage ;;
esac
. git-parse-remote
remote=$(get_remote_url "$@")
case "$has_all" in
--all)
set x ;;
'')
case "$do_tags,$#" in
yes,1)
set x $(cd "$GIT_DIR/refs" && find tags -type f -print) ;;
yes,*)
set x $(cd "$GIT_DIR/refs" && find tags -type f -print) \
$(get_remote_refs_for_push "$@") ;;
,*)
set x $(get_remote_refs_for_push "$@") ;;
esac
esac
shift ;# away the initial 'x'
# $# is now 0 if there was no explicit refspec on the command line
# and there was no default refspec to push from remotes/ file.
# we will let git-send-pack to do its "matching refs" thing.
case "$remote" in
git://*)
die "Cannot use READ-ONLY transport to push to $remote" ;;
rsync://*)
die "Pushing with rsync transport is deprecated" ;;
esac
set x "$remote" "$@"; shift
test "$has_all" && set x "$has_all" "$@" && shift
test "$has_force" && set x "$has_force" "$@" && shift
test "$has_exec" && set x "$has_exec" "$@" && shift
test "$has_thin" && set x "$has_thin" "$@" && shift
case "$remote" in
http://* | https://*)
exec git-http-push "$@";;
*)
exec git-send-pack "$@";;
esac

View File

@ -277,14 +277,11 @@ onto=$(git-rev-parse --verify "${onto_name}^0") || exit
# Check if we are already based on $onto, but this should be
# done only when upstream and onto are the same.
if test "$upstream" = "$onto"
mb=$(git-merge-base "$onto" "$branch")
if test "$upstream" = "$onto" && test "$mb" = "$onto"
then
mb=$(git-merge-base "$onto" "$branch")
if test "$mb" = "$onto"
then
echo >&2 "Current branch $branch_name is up to date."
exit 0
fi
echo >&2 "Current branch $branch_name is up to date."
exit 0
fi
# Rewind the head to "$onto"; this saves our current head in ORIG_HEAD.
@ -292,9 +289,9 @@ git-reset --hard "$onto"
# If the $onto is a proper descendant of the tip of the branch, then
# we just fast forwarded.
if test "$mb" = "$onto"
if test "$mb" = "$branch"
then
echo >&2 "Fast-forwarded $branch to $newbase."
echo >&2 "Fast-forwarded $branch_name to $onto_name."
exit 0
fi

View File

@ -35,17 +35,12 @@ case "$1" in
exit
esac
# Make sure we are in a valid repository of a vintage we understand.
if [ -z "$SUBDIRECTORY_OK" ]
then
: ${GIT_DIR=.git}
: ${GIT_OBJECT_DIRECTORY="$GIT_DIR/objects"}
# Make sure we are in a valid repository of a vintage we understand.
GIT_DIR="$GIT_DIR" git repo-config --get core.nosuch >/dev/null
if test $? = 128
then
exit
fi
GIT_DIR=$(GIT_DIR="$GIT_DIR" git-rev-parse --git-dir) || exit
else
GIT_DIR=$(git-rev-parse --git-dir) || exit
fi
: ${GIT_OBJECT_DIRECTORY="$GIT_DIR/objects"}

View File

@ -31,6 +31,7 @@ use File::Basename qw/dirname basename/;
use File::Path qw/mkpath/;
use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev pass_through/;
use File::Spec qw//;
use File::Copy qw/copy/;
use POSIX qw/strftime/;
use IPC::Open3;
use Memoize;
@ -77,9 +78,6 @@ my %cmt_opts = ( 'edit|e' => \$_edit,
'copy-similarity|C=i'=> \$_cp_similarity
);
# yes, 'native' sets "\n". Patches to fix this for non-*nix systems welcome:
my %EOL = ( CR => "\015", LF => "\012", CRLF => "\015\012", native => "\012" );
my %cmd = (
fetch => [ \&fetch, "Download new revisions from SVN",
{ 'revision|r=s' => \$_revision, %fc_opts } ],
@ -1160,27 +1158,24 @@ sub repo_path_split {
}
}
my ($url, $path) = ($full_url =~ m!^([a-z\+]+://[^/]*)(.*)$!i);
$path =~ s#^/+##;
my @paths = split(m#/+#, $path);
if ($_use_lib) {
while (1) {
$SVN = libsvn_connect($url);
last if (defined $SVN &&
defined eval { $SVN->get_latest_revnum });
my $n = shift @paths || last;
$url .= "/$n";
}
my $tmp = libsvn_connect($full_url);
my $url = $tmp->get_repos_root;
$full_url =~ s#^\Q$url\E/*##;
push @repo_path_split_cache, qr/^(\Q$url\E)/;
return ($url, $full_url);
} else {
my ($url, $path) = ($full_url =~ m!^([a-z\+]+://[^/]*)(.*)$!i);
$path =~ s#^/+##;
my @paths = split(m#/+#, $path);
while (quiet_run(qw/svn ls --non-interactive/, $url)) {
my $n = shift @paths || last;
$url .= "/$n";
}
push @repo_path_split_cache, qr/^(\Q$url\E)/;
$path = join('/',@paths);
return ($url, $path);
}
push @repo_path_split_cache, qr/^(\Q$url\E)/;
$path = join('/',@paths);
return ($url, $path);
}
sub setup_git_svn {
@ -1760,43 +1755,6 @@ sub svn_info {
sub sys { system(@_) == 0 or croak $? }
sub eol_cp {
my ($from, $to) = @_;
my $es = svn_propget_base('svn:eol-style', $to);
open my $rfd, '<', $from or croak $!;
binmode $rfd or croak $!;
open my $wfd, '>', $to or croak $!;
binmode $wfd or croak $!;
eol_cp_fd($rfd, $wfd, $es);
close $rfd or croak $!;
close $wfd or croak $!;
}
sub eol_cp_fd {
my ($rfd, $wfd, $es) = @_;
my $eol = defined $es ? $EOL{$es} : undef;
my $buf;
use bytes;
while (1) {
my ($r, $w, $t);
defined($r = sysread($rfd, $buf, 4096)) or croak $!;
return unless $r;
if ($eol) {
if ($buf =~ /\015$/) {
my $c;
defined($r = sysread($rfd,$c,1)) or croak $!;
$buf .= $c if $r > 0;
}
$buf =~ s/(?:\015\012|\015|\012)/$eol/gs;
$r = length($buf);
}
for ($w = 0; $w < $r; $w += $t) {
$t = syswrite($wfd, $buf, $r - $w, $w) or croak $!;
}
}
no bytes;
}
sub do_update_index {
my ($z_cmd, $cmd, $no_text_base) = @_;
@ -1824,9 +1782,11 @@ sub do_update_index {
'text-base',"$f.svn-base");
$tb =~ s#^/##;
}
my @s = stat($x);
unlink $x or croak $!;
eol_cp($tb, $x);
copy($tb, $x);
chmod(($mode &~ umask), $x) or croak $!;
utime $s[8], $s[9], $x;
}
print $ui $x,"\0";
}
@ -2617,7 +2577,9 @@ sub libsvn_connect {
sub libsvn_get_file {
my ($gui, $f, $rev) = @_;
my $p = $f;
return unless ($p =~ s#^\Q$SVN_PATH\E/##);
if (length $SVN_PATH > 0) {
return unless ($p =~ s#^\Q$SVN_PATH\E/##);
}
my ($hash, $pid, $in, $out);
my $pool = SVN::Pool->new;
@ -2664,6 +2626,7 @@ sub libsvn_log_entry {
if (defined $_authors && ! defined $users{$author}) {
die "Author: $author not defined in $_authors file\n";
}
$msg = '' if ($rev == 0 && !defined $msg);
return { revision => $rev, date => "+0000 $Y-$m-$d $H:$M:$S",
author => $author, msg => $msg."\n", parents => $parents || [] }
}

24
git.c
View File

@ -15,6 +15,9 @@
#include "builtin.h"
const char git_usage_string[] =
"git [--version] [--exec-path[=GIT_EXEC_PATH]] [--help] COMMAND [ ARGS ]";
static void prepend_to_path(const char *dir, int len)
{
const char *old_path = getenv("PATH");
@ -78,7 +81,7 @@ static int handle_options(const char*** argv, int* argc)
setenv("GIT_DIR", getcwd(git_dir, 1024), 1);
} else {
fprintf(stderr, "Unknown option: %s\n", cmd);
cmd_usage(0, NULL, NULL);
usage(git_usage_string);
}
(*argv)++;
@ -211,6 +214,7 @@ static int handle_alias(int *argcp, const char ***argv)
const char git_version_string[] = GIT_VERSION;
#define NEEDS_PREFIX 1
#define USE_PAGER 2
static void handle_internal_command(int argc, const char **argv, char **envp)
{
@ -218,14 +222,14 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
static struct cmd_struct {
const char *cmd;
int (*fn)(int, const char **, const char *);
int prefix;
int option;
} commands[] = {
{ "version", cmd_version },
{ "help", cmd_help },
{ "log", cmd_log, NEEDS_PREFIX },
{ "whatchanged", cmd_whatchanged, NEEDS_PREFIX },
{ "show", cmd_show, NEEDS_PREFIX },
{ "push", cmd_push },
{ "log", cmd_log, NEEDS_PREFIX | USE_PAGER },
{ "whatchanged", cmd_whatchanged, NEEDS_PREFIX | USE_PAGER },
{ "show", cmd_show, NEEDS_PREFIX | USE_PAGER },
{ "push", cmd_push, NEEDS_PREFIX },
{ "format-patch", cmd_format_patch, NEEDS_PREFIX },
{ "count-objects", cmd_count_objects },
{ "diff", cmd_diff, NEEDS_PREFIX },
@ -259,6 +263,8 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
{ "fmt-merge-msg", cmd_fmt_merge_msg, NEEDS_PREFIX },
{ "prune", cmd_prune, NEEDS_PREFIX },
{ "mv", cmd_mv, NEEDS_PREFIX },
{ "prune-packed", cmd_prune_packed, NEEDS_PREFIX },
{ "repo-config", cmd_repo_config },
};
int i;
@ -275,8 +281,10 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
continue;
prefix = NULL;
if (p->prefix)
if (p->option & NEEDS_PREFIX)
prefix = setup_git_directory();
if (p->option & USE_PAGER)
setup_pager();
if (getenv("GIT_TRACE")) {
int i;
fprintf(stderr, "trace: built-in: git");
@ -372,7 +380,7 @@ int main(int argc, const char **argv, char **envp)
}
if (errno == ENOENT)
cmd_usage(0, exec_path, "'%s' is not a git-command", cmd);
help_unknown_cmd(cmd);
fprintf(stderr, "Failed to run command '%s': %s\n",
cmd, strerror(errno));

149
gitk
View File

@ -312,7 +312,7 @@ proc getcommit {id} {
proc readrefs {} {
global tagids idtags headids idheads tagcontents
global otherrefids idotherrefs
global otherrefids idotherrefs mainhead
foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
catch {unset $v}
@ -358,6 +358,13 @@ proc readrefs {} {
}
}
close $refd
set mainhead {}
catch {
set thehead [exec git symbolic-ref HEAD]
if {[string match "refs/heads/*" $thehead]} {
set mainhead [string range $thehead 11 end]
}
}
}
proc show_error {w top msg} {
@ -386,6 +393,7 @@ proc makewindow {} {
global rowctxmenu mergemax wrapcomment
global highlight_files gdttype
global searchstring sstring
global bgcolor fgcolor bglist fglist diffcolors
menu .bar
.bar add cascade -label "File" -menu .bar.file
@ -446,18 +454,19 @@ proc makewindow {} {
.ctop add .ctop.top
set canv .ctop.top.clist.canv
canvas $canv -height $geometry(canvh) -width $geometry(canv1) \
-bg white -bd 0 \
-background $bgcolor -bd 0 \
-yscrollincr $linespc -yscrollcommand "scrollcanv $cscroll"
.ctop.top.clist add $canv
set canv2 .ctop.top.clist.canv2
canvas $canv2 -height $geometry(canvh) -width $geometry(canv2) \
-bg white -bd 0 -yscrollincr $linespc
-background $bgcolor -bd 0 -yscrollincr $linespc
.ctop.top.clist add $canv2
set canv3 .ctop.top.clist.canv3
canvas $canv3 -height $geometry(canvh) -width $geometry(canv3) \
-bg white -bd 0 -yscrollincr $linespc
-background $bgcolor -bd 0 -yscrollincr $linespc
.ctop.top.clist add $canv3
bind .ctop.top.clist <Configure> {resizeclistpanes %W %w}
lappend bglist $canv $canv2 $canv3
set sha1entry .ctop.top.bar.sha1
set entries $sha1entry
@ -563,19 +572,22 @@ proc makewindow {} {
trace add variable searchstring write incrsearch
pack $sstring -side left -expand 1 -fill x
set ctext .ctop.cdet.left.ctext
text $ctext -bg white -state disabled -font $textfont \
text $ctext -background $bgcolor -foreground $fgcolor \
-state disabled -font $textfont \
-width $geometry(ctextw) -height $geometry(ctexth) \
-yscrollcommand scrolltext -wrap none
scrollbar .ctop.cdet.left.sb -command "$ctext yview"
pack .ctop.cdet.left.sb -side right -fill y
pack $ctext -side left -fill both -expand 1
.ctop.cdet add .ctop.cdet.left
lappend bglist $ctext
lappend fglist $ctext
$ctext tag conf comment -wrap $wrapcomment
$ctext tag conf filesep -font [concat $textfont bold] -back "#aaaaaa"
$ctext tag conf hunksep -fore blue
$ctext tag conf d0 -fore red
$ctext tag conf d1 -fore "#00a000"
$ctext tag conf hunksep -fore [lindex $diffcolors 2]
$ctext tag conf d0 -fore [lindex $diffcolors 0]
$ctext tag conf d1 -fore [lindex $diffcolors 1]
$ctext tag conf m0 -fore red
$ctext tag conf m1 -fore blue
$ctext tag conf m2 -fore green
@ -608,11 +620,15 @@ proc makewindow {} {
pack .ctop.cdet.right.mode -side top -fill x
set cflist .ctop.cdet.right.cfiles
set indent [font measure $mainfont "nn"]
text $cflist -width $geometry(cflistw) -background white -font $mainfont \
text $cflist -width $geometry(cflistw) \
-background $bgcolor -foreground $fgcolor \
-font $mainfont \
-tabs [list $indent [expr {2 * $indent}]] \
-yscrollcommand ".ctop.cdet.right.sb set" \
-cursor [. cget -cursor] \
-spacing1 1 -spacing3 1
lappend bglist $cflist
lappend fglist $cflist
scrollbar .ctop.cdet.right.sb -command "$cflist yview"
pack .ctop.cdet.right.sb -side right -fill y
pack $cflist -side left -fill both -expand 1
@ -747,6 +763,7 @@ proc savestuff {w} {
global maxwidth showneartags
global viewname viewfiles viewargs viewperm nextviewnum
global cmitmode wrapcomment
global colors bgcolor fgcolor diffcolors
if {$stuffsaved} return
if {![winfo viewable .]} return
@ -761,6 +778,10 @@ proc savestuff {w} {
puts $f [list set cmitmode $cmitmode]
puts $f [list set wrapcomment $wrapcomment]
puts $f [list set showneartags $showneartags]
puts $f [list set bgcolor $bgcolor]
puts $f [list set fgcolor $fgcolor]
puts $f [list set colors $colors]
puts $f [list set diffcolors $diffcolors]
puts $f "set geometry(width) [winfo width .ctop]"
puts $f "set geometry(height) [winfo height .ctop]"
puts $f "set geometry(canv1) [expr {[winfo width $canv]-2}]"
@ -2870,11 +2891,11 @@ proc drawlines {id} {
}
proc drawcmittext {id row col rmx} {
global linespc canv canv2 canv3 canvy0
global linespc canv canv2 canv3 canvy0 fgcolor
global commitlisted commitinfo rowidlist
global rowtextx idpos idtags idheads idotherrefs
global linehtag linentag linedtag
global mainfont canvxmax boldrows boldnamerows
global mainfont canvxmax boldrows boldnamerows fgcolor
set ofill [expr {[lindex $commitlisted $row]? "blue": "white"}]
set x [xc $row $col]
@ -2882,7 +2903,7 @@ proc drawcmittext {id row col rmx} {
set orad [expr {$linespc / 3}]
set t [$canv create oval [expr {$x - $orad}] [expr {$y - $orad}] \
[expr {$x + $orad - 1}] [expr {$y + $orad - 1}] \
-fill $ofill -outline black -width 1]
-fill $ofill -outline $fgcolor -width 1 -tags circle]
$canv raise $t
$canv bind $t <1> {selcanvline {} %x %y}
set xt [xc $row [llength [lindex $rowidlist $row]]]
@ -2910,13 +2931,13 @@ proc drawcmittext {id row col rmx} {
lappend nfont bold
}
}
set linehtag($row) [$canv create text $xt $y -anchor w \
-text $headline -font $font]
set linehtag($row) [$canv create text $xt $y -anchor w -fill $fgcolor \
-text $headline -font $font -tags text]
$canv bind $linehtag($row) <Button-3> "rowmenu %X %Y $id"
set linentag($row) [$canv2 create text 3 $y -anchor w \
-text $name -font $nfont]
set linedtag($row) [$canv3 create text 3 $y -anchor w \
-text $date -font $mainfont]
set linentag($row) [$canv2 create text 3 $y -anchor w -fill $fgcolor \
-text $name -font $nfont -tags text]
set linedtag($row) [$canv3 create text 3 $y -anchor w -fill $fgcolor \
-text $date -font $mainfont -tags text]
set xr [expr {$xt + [font measure $mainfont $headline]}]
if {$xr > $canvxmax} {
set canvxmax $xr
@ -3136,9 +3157,9 @@ proc bindline {t id} {
}
proc drawtags {id x xt y1} {
global idtags idheads idotherrefs
global idtags idheads idotherrefs mainhead
global linespc lthickness
global canv mainfont commitrow rowtextx curview
global canv mainfont commitrow rowtextx curview fgcolor bgcolor
set marks {}
set ntags 0
@ -3163,8 +3184,14 @@ proc drawtags {id x xt y1} {
set yb [expr {$yt + $linespc - 1}]
set xvals {}
set wvals {}
set i -1
foreach tag $marks {
set wid [font measure $mainfont $tag]
incr i
if {$i >= $ntags && $i < $ntags + $nheads && $tag eq $mainhead} {
set wid [font measure [concat $mainfont bold] $tag]
} else {
set wid [font measure $mainfont $tag]
}
lappend xvals $xt
lappend wvals $wid
set xt [expr {$xt + $delta + $wid + $lthickness + $linespc}]
@ -3175,6 +3202,7 @@ proc drawtags {id x xt y1} {
foreach tag $marks x $xvals wid $wvals {
set xl [expr {$x + $delta}]
set xr [expr {$x + $delta + $wid + $lthickness}]
set font $mainfont
if {[incr ntags -1] >= 0} {
# draw a tag
set t [$canv create polygon $x [expr {$yt + $delta}] $xl $yt \
@ -3186,6 +3214,9 @@ proc drawtags {id x xt y1} {
# draw a head or other ref
if {[incr nheads -1] >= 0} {
set col green
if {$tag eq $mainhead} {
lappend font bold
}
} else {
set col "#ddddff"
}
@ -3201,8 +3232,8 @@ proc drawtags {id x xt y1} {
-width 0 -fill "#ffddaa" -tags tag.$id
}
}
set t [$canv create text $xl $y1 -anchor w -text $tag \
-font $mainfont -tags tag.$id]
set t [$canv create text $xl $y1 -anchor w -text $tag -fill $fgcolor \
-font $font -tags [list tag.$id text]]
if {$ntags >= 0} {
$canv bind $t <1> [list showtag $tag 1]
}
@ -3223,10 +3254,11 @@ proc xcoord {i level ln} {
}
proc show_status {msg} {
global canv mainfont
global canv mainfont fgcolor
clear_display
$canv create text 3 3 -anchor nw -text $msg -font $mainfont -tags textitems
$canv create text 3 3 -anchor nw -text $msg -font $mainfont \
-tags text -fill $fgcolor
}
proc finishcommits {} {
@ -4574,7 +4606,8 @@ proc linehover {} {
set t [$canv create rectangle $x0 $y0 $x1 $y1 \
-fill \#ffff80 -outline black -width 1 -tags hover]
$canv raise $t
set t [$canv create text $x $y -anchor nw -text $text -tags hover -font $mainfont]
set t [$canv create text $x $y -anchor nw -text $text -tags hover \
-font $mainfont]
$canv raise $t
}
@ -4901,7 +4934,7 @@ proc domktag {} {
proc redrawtags {id} {
global canv linehtag commitrow idpos selectedline curview
global mainfont
global mainfont canvxmax
if {![info exists commitrow($curview,$id)]} return
drawcmitrow $commitrow($curview,$id)
@ -5242,6 +5275,7 @@ proc doquit {} {
proc doprefs {} {
global maxwidth maxgraphpct diffopts
global oldprefs prefstop showneartags
global bgcolor fgcolor ctext diffcolors
set top .gitkprefs
set prefstop $top
@ -5265,6 +5299,7 @@ proc doprefs {} {
-font optionfont
spinbox $top.maxpct -from 1 -to 100 -width 4 -textvariable maxgraphpct
grid x $top.maxpctl $top.maxpct -sticky w
label $top.ddisp -text "Diff display options"
grid $top.ddisp - -sticky w -pady 10
label $top.diffoptl -text "Options for diff program" \
@ -5276,6 +5311,34 @@ proc doprefs {} {
checkbutton $top.ntag.b -variable showneartags
pack $top.ntag.b $top.ntag.l -side left
grid x $top.ntag -sticky w
label $top.cdisp -text "Colors: press to choose"
grid $top.cdisp - -sticky w -pady 10
label $top.bg -padx 40 -relief sunk -background $bgcolor
button $top.bgbut -text "Background" -font optionfont \
-command [list choosecolor bgcolor 0 $top.bg background setbg]
grid x $top.bgbut $top.bg -sticky w
label $top.fg -padx 40 -relief sunk -background $fgcolor
button $top.fgbut -text "Foreground" -font optionfont \
-command [list choosecolor fgcolor 0 $top.fg foreground setfg]
grid x $top.fgbut $top.fg -sticky w
label $top.diffold -padx 40 -relief sunk -background [lindex $diffcolors 0]
button $top.diffoldbut -text "Diff: old lines" -font optionfont \
-command [list choosecolor diffcolors 0 $top.diffold "diff old lines" \
[list $ctext tag conf d0 -foreground]]
grid x $top.diffoldbut $top.diffold -sticky w
label $top.diffnew -padx 40 -relief sunk -background [lindex $diffcolors 1]
button $top.diffnewbut -text "Diff: new lines" -font optionfont \
-command [list choosecolor diffcolors 1 $top.diffnew "diff new lines" \
[list $ctext tag conf d1 -foreground]]
grid x $top.diffnewbut $top.diffnew -sticky w
label $top.hunksep -padx 40 -relief sunk -background [lindex $diffcolors 2]
button $top.hunksepbut -text "Diff: hunk header" -font optionfont \
-command [list choosecolor diffcolors 2 $top.hunksep \
"diff hunk header" \
[list $ctext tag conf hunksep -foreground]]
grid x $top.hunksepbut $top.hunksep -sticky w
frame $top.buts
button $top.buts.ok -text "OK" -command prefsok
button $top.buts.can -text "Cancel" -command prefscan
@ -5285,6 +5348,35 @@ proc doprefs {} {
grid $top.buts - - -pady 10 -sticky ew
}
proc choosecolor {v vi w x cmd} {
global $v
set c [tk_chooseColor -initialcolor [lindex [set $v] $vi] \
-title "Gitk: choose color for $x"]
if {$c eq {}} return
$w conf -background $c
lset $v $vi $c
eval $cmd $c
}
proc setbg {c} {
global bglist
foreach w $bglist {
$w conf -background $c
}
}
proc setfg {c} {
global fglist canv
foreach w $fglist {
$w conf -foreground $c
}
allcanvs itemconf text -fill $c
$canv itemconf circle -outline $c
}
proc prefscan {} {
global maxwidth maxgraphpct diffopts
global oldprefs prefstop showneartags
@ -5620,6 +5712,9 @@ set wrapcomment "none"
set showneartags 1
set colors {green red blue magenta darkgrey brown orange}
set bgcolor white
set fgcolor black
set diffcolors {red "#00a000" blue}
catch {source ~/.gitk}

View File

@ -46,7 +46,7 @@ int main(int argc, char **argv)
if (!no_more_flags && argv[i][0] == '-') {
if (!strcmp(argv[i], "-t")) {
if (argc <= ++i)
die(hash_object_usage);
usage(hash_object_usage);
type = argv[i];
}
else if (!strcmp(argv[i], "-w")) {
@ -66,8 +66,8 @@ int main(int argc, char **argv)
hash_stdin(type, write_object);
}
else
die(hash_object_usage);
}
usage(hash_object_usage);
}
else {
const char *arg = argv[i];
if (0 <= prefix_length)

View File

@ -870,7 +870,7 @@ static void process_ls_pack(struct remote_ls_ctx *ls)
if (strlen(ls->dentry_name) == 63 &&
!strncmp(ls->dentry_name, "objects/pack/pack-", 18) &&
!strncmp(ls->dentry_name+58, ".pack", 5)) {
has_extension(ls->dentry_name, ".pack")) {
get_sha1_hex(ls->dentry_name + 18, sha1);
setup_index(ls->repo, sha1);
}
@ -1226,6 +1226,7 @@ int main(int argc, const char **argv)
int arg = 1;
int rc = 0;
setup_ident();
setup_git_directory();
git_config(git_default_config);

View File

@ -530,7 +530,7 @@ static void start_put(struct transfer_request *request)
request->dest = xmalloc(strlen(request->url) + 14);
sprintf(request->dest, "Destination: %s", request->url);
posn += 38;
*(posn++) = '.';
*(posn++) = '_';
strcpy(posn, request->lock->token);
slot = get_active_slot();

View File

@ -447,7 +447,7 @@ int main(int argc, char **argv)
usage(index_pack_usage);
if (!index_name) {
int len = strlen(pack_name);
if (len < 5 || strcmp(pack_name + len - 5, ".pack"))
if (!has_extension(pack_name, ".pack"))
die("packfile name '%s' does not end with '.pack'",
pack_name);
index_name_buf = xmalloc(len);

View File

@ -43,8 +43,8 @@ static int setup_indices(void)
return -1;
while ((de = readdir(dir)) != NULL) {
int namelen = strlen(de->d_name);
if (namelen != 50 ||
strcmp(de->d_name + namelen - 5, ".pack"))
if (namelen != 50 ||
!has_extension(de->d_name, ".pack"))
continue;
get_sha1_hex(de->d_name + 5, sha1);
setup_index(sha1);
@ -210,6 +210,7 @@ int main(int argc, const char **argv)
char **commit_id;
int arg = 1;
setup_ident();
setup_git_directory();
git_config(git_default_config);

View File

@ -22,7 +22,7 @@ static void remove_lock_file_on_signal(int signo)
raise(signo);
}
int hold_lock_file_for_update(struct lock_file *lk, const char *path)
static int lock_file(struct lock_file *lk, const char *path)
{
int fd;
sprintf(lk->filename, "%s.lock", path);
@ -41,6 +41,14 @@ int hold_lock_file_for_update(struct lock_file *lk, const char *path)
return fd;
}
int hold_lock_file_for_update(struct lock_file *lk, const char *path, int die_on_error)
{
int fd = lock_file(lk, path);
if (fd < 0 && die_on_error)
die("unable to create '%s': %s", path, strerror(errno));
return fd;
}
int commit_lock_file(struct lock_file *lk)
{
char result_file[PATH_MAX];

View File

@ -59,7 +59,7 @@ void show_log(struct rev_info *opt, const char *sep)
fputs(diff_unique_abbrev(commit->object.sha1, abbrev_commit), stdout);
if (opt->parents)
show_parents(commit, abbrev_commit);
putchar('\n');
putchar(opt->diffopt.line_termination);
return;
}

View File

@ -125,9 +125,7 @@ static int flush_cache(void)
{
/* flush temporary index */
struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
int fd = hold_lock_file_for_update(lock, current_index_file);
if (fd < 0)
die("could not lock %s", lock->filename);
int fd = hold_lock_file_for_update(lock, current_index_file, 1);
if (write_cache(fd, active_cache, active_nr) ||
close(fd) || commit_lock_file(lock))
die ("unable to write %s", current_index_file);

45
mktag.c
View File

@ -2,10 +2,11 @@
#include "tag.h"
/*
* A signature file has a very simple fixed format: three lines
* of "object <sha1>" + "type <typename>" + "tag <tagname>",
* followed by some free-form signature that git itself doesn't
* care about, but that can be verified with gpg or similar.
* A signature file has a very simple fixed format: four lines
* of "object <sha1>" + "type <typename>" + "tag <tagname>" +
* "tagger <committer>", followed by a blank line, a free-form tag
* message and a signature block that git itself doesn't care about,
* but that can be verified with gpg or similar.
*
* The first three lines are guaranteed to be at least 63 bytes:
* "object <sha1>\n" is 48 bytes, "type tag\n" at 9 bytes is the
@ -38,6 +39,12 @@ static int verify_object(unsigned char *sha1, const char *expected_type)
return ret;
}
#ifdef NO_C99_FORMAT
#define PD_FMT "%d"
#else
#define PD_FMT "%td"
#endif
static int verify_tag(char *buffer, unsigned long size)
{
int typelen;
@ -46,45 +53,42 @@ static int verify_tag(char *buffer, unsigned long size)
const char *object, *type_line, *tag_line, *tagger_line;
if (size < 64)
return error("wanna fool me ? you obviously got the size wrong !\n");
return error("wanna fool me ? you obviously got the size wrong !");
buffer[size] = 0;
/* Verify object line */
object = buffer;
if (memcmp(object, "object ", 7))
return error("char%d: does not start with \"object \"\n", 0);
return error("char%d: does not start with \"object \"", 0);
if (get_sha1_hex(object + 7, sha1))
return error("char%d: could not get SHA1 hash\n", 7);
return error("char%d: could not get SHA1 hash", 7);
/* Verify type line */
type_line = object + 48;
if (memcmp(type_line - 1, "\ntype ", 6))
return error("char%d: could not find \"\\ntype \"\n", 47);
return error("char%d: could not find \"\\ntype \"", 47);
/* Verify tag-line */
tag_line = strchr(type_line, '\n');
if (!tag_line)
return error("char%td: could not find next \"\\n\"\n", type_line - buffer);
return error("char" PD_FMT ": could not find next \"\\n\"", type_line - buffer);
tag_line++;
if (memcmp(tag_line, "tag ", 4) || tag_line[4] == '\n')
return error("char%td: no \"tag \" found\n", tag_line - buffer);
return error("char" PD_FMT ": no \"tag \" found", tag_line - buffer);
/* Get the actual type */
typelen = tag_line - type_line - strlen("type \n");
if (typelen >= sizeof(type))
return error("char%td: type too long\n", type_line+5 - buffer);
return error("char" PD_FMT ": type too long", type_line+5 - buffer);
memcpy(type, type_line+5, typelen);
type[typelen] = 0;
/* Verify that the object matches */
if (get_sha1_hex(object + 7, sha1))
return error("char%d: could not get SHA1 hash but this is really odd since i got it before !\n", 7);
if (verify_object(sha1, type))
return error("char%d: could not verify object %s\n", 7, sha1);
return error("char%d: could not verify object %s", 7, sha1_to_hex(sha1));
/* Verify the tag-name: we don't allow control characters or spaces in it */
tag_line += 4;
@ -94,19 +98,24 @@ static int verify_tag(char *buffer, unsigned long size)
break;
if (c > ' ')
continue;
return error("char%td: could not verify tag name\n", tag_line - buffer);
return error("char" PD_FMT ": could not verify tag name", tag_line - buffer);
}
/* Verify the tagger line */
tagger_line = tag_line;
if (memcmp(tagger_line, "tagger", 6) || (tagger_line[6] == '\n'))
return error("char%td: could not find \"tagger\"\n", tagger_line - buffer);
return error("char" PD_FMT ": could not find \"tagger\"", tagger_line - buffer);
/* TODO: check for committer info + blank line? */
/* Also, the minimum length is probably + "tagger .", or 63+8=71 */
/* The actual stuff afterwards we don't care about.. */
return 0;
}
#undef PD_FMT
int main(int argc, char **argv)
{
unsigned long size = 4096;
@ -114,7 +123,7 @@ int main(int argc, char **argv)
unsigned char result_sha1[20];
if (argc != 1)
usage("cat <signaturefile> | git-mktag");
usage("git-mktag < signaturefile");
setup_git_directory();

View File

@ -71,7 +71,7 @@ static void write_tree(unsigned char *sha1)
write_sha1_file(buffer, offset, tree_type, sha1);
}
static const char mktree_usage[] = "mktree [-z]";
static const char mktree_usage[] = "git-mktree [-z]";
int main(int ac, char **av)
{

View File

@ -61,7 +61,7 @@ static int ce_compare_data(struct cache_entry *ce, struct stat *st)
unsigned char sha1[20];
if (!index_fd(sha1, fd, st, 0, NULL))
match = memcmp(sha1, ce->sha1, 20);
close(fd);
/* index_fd() closed the file descriptor already */
}
return match;
}

10
refs.c
View File

@ -147,7 +147,7 @@ static int do_for_each_ref(const char *base, int (*fn)(const char *path, const u
namelen = strlen(de->d_name);
if (namelen > 255)
continue;
if (namelen>5 && !strcmp(de->d_name+namelen-5,".lock"))
if (has_extension(de->d_name, ".lock"))
continue;
memcpy(path + baselen, de->d_name, namelen+1);
if (stat(git_path("%s", path), &st) < 0)
@ -319,13 +319,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *path,
if (safe_create_leading_directories(lock->ref_file))
die("unable to create directory for %s", lock->ref_file);
lock->lock_fd = hold_lock_file_for_update(lock->lk, lock->ref_file);
if (lock->lock_fd < 0) {
error("Couldn't open lock file %s: %s",
lock->lk->filename, strerror(errno));
unlock_ref(lock);
return NULL;
}
lock->lock_fd = hold_lock_file_for_update(lock->lk, lock->ref_file, 1);
return old_sha1 ? verify_lock(lock, old_sha1, mustexist) : lock;
}

View File

@ -936,7 +936,8 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
revs->diffopt.output_format = DIFF_FORMAT_PATCH;
}
revs->diffopt.abbrev = revs->abbrev;
diff_setup_done(&revs->diffopt);
if (diff_setup_done(&revs->diffopt) < 0)
die("diff_setup_done failed");
return left;
}

View File

@ -184,7 +184,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
}
return NULL;
bad_dir_environ:
if (!nongit_ok) {
if (nongit_ok) {
*nongit_ok = 1;
return NULL;
}

View File

@ -590,7 +590,7 @@ static void prepare_packed_git_one(char *objdir, int local)
int namelen = strlen(de->d_name);
struct packed_git *p;
if (strcmp(de->d_name + namelen - 4, ".idx"))
if (!has_extension(de->d_name, ".idx"))
continue;
/* we have .idx. Is it a file we can map? */

View File

@ -193,7 +193,7 @@ const char *find_unique_abbrev(const unsigned char *sha1, int len)
is_null = !memcmp(sha1, null_sha1, 20);
memcpy(hex, sha1_to_hex(sha1), 40);
if (len == 40)
if (len == 40 || !len)
return hex;
while (len < 40) {
unsigned char sha1_ret[20];

View File

@ -132,6 +132,7 @@ int main(int argc, char **argv)
prog = getenv("GIT_SSH_PUSH");
if (!prog) prog = "git-ssh-upload";
setup_ident();
setup_git_directory();
git_config(git_default_config);

View File

@ -4,7 +4,8 @@
check_count () {
head=
case "$1" in -h) head="$2"; shift; shift ;; esac
$PROG file $head | perl -e '
$PROG file $head >.result || return 1
cat .result | perl -e '
my %expect = (@ARGV);
my %count = ();
while (<STDIN>) {

27
t/t1003-read-tree-prefix.sh Executable file
View File

@ -0,0 +1,27 @@
#!/bin/sh
#
# Copyright (c) 2006 Junio C Hamano
#
test_description='git-read-tree --prefix test.
'
. ./test-lib.sh
test_expect_success setup '
echo hello >one &&
git-update-index --add one &&
tree=`git-write-tree` &&
echo tree is $tree
'
echo 'one
two/one' >expect
test_expect_success 'read-tree --prefix' '
git-read-tree --prefix=two/ $tree &&
git-ls-files >actual &&
cmp expect actual
'
test_done

109
t/t1020-subdirectory.sh Executable file
View File

@ -0,0 +1,109 @@
#!/bin/sh
#
# Copyright (c) 2006 Junio C Hamano
#
test_description='Try various core-level commands in subdirectory.
'
. ./test-lib.sh
test_expect_success setup '
long="a b c d e f g h i j k l m n o p q r s t u v w x y z" &&
for c in $long; do echo $c; done >one &&
mkdir dir &&
for c in x y z $long a b c; do echo $c; done >dir/two &&
cp one original.one &&
cp dir/two original.two
'
HERE=`pwd`
LF='
'
test_expect_success 'update-index and ls-files' '
cd $HERE &&
git-update-index --add one &&
case "`git-ls-files`" in
one) echo ok one ;;
*) echo bad one; exit 1 ;;
esac &&
cd dir &&
git-update-index --add two &&
case "`git-ls-files`" in
two) echo ok two ;;
*) echo bad two; exit 1 ;;
esac &&
cd .. &&
case "`git-ls-files`" in
dir/two"$LF"one) echo ok both ;;
*) echo bad; exit 1 ;;
esac
'
test_expect_success 'cat-file' '
cd $HERE &&
two=`git-ls-files -s dir/two` &&
two=`expr "$two" : "[0-7]* \\([0-9a-f]*\\)"` &&
echo "$two" &&
git-cat-file -p "$two" >actual &&
cmp dir/two actual &&
cd dir &&
git-cat-file -p "$two" >actual &&
cmp two actual
'
rm -f actual dir/actual
test_expect_success 'diff-files' '
cd $HERE &&
echo a >>one &&
echo d >>dir/two &&
case "`git-diff-files --name-only`" in
dir/two"$LF"one) echo ok top ;;
*) echo bad top; exit 1 ;;
esac &&
# diff should not omit leading paths
cd dir &&
case "`git-diff-files --name-only`" in
dir/two"$LF"one) echo ok subdir ;;
*) echo bad subdir; exit 1 ;;
esac &&
case "`git-diff-files --name-only .`" in
dir/two) echo ok subdir limited ;;
*) echo bad subdir limited; exit 1 ;;
esac
'
test_expect_success 'write-tree' '
cd $HERE &&
top=`git-write-tree` &&
echo $top &&
cd dir &&
sub=`git-write-tree` &&
echo $sub &&
test "z$top" = "z$sub"
'
test_expect_success 'checkout-index' '
cd $HERE &&
git-checkout-index -f -u one &&
cmp one original.one &&
cd dir &&
git-checkout-index -f -u two &&
cmp two ../original.two
'
test_expect_success 'read-tree' '
cd $HERE &&
rm -f one dir/two &&
tree=`git-write-tree` &&
git-read-tree --reset -u "$tree" &&
cmp one original.one &&
cmp dir/two original.two &&
cd dir &&
rm -f two &&
git-read-tree --reset -u "$tree" &&
cmp two ../original.two &&
cmp ../one ../original.one
'
test_done

227
t/t3800-mktag.sh Executable file
View File

@ -0,0 +1,227 @@
#!/bin/sh
#
#
test_description='git-mktag: tag object verify test'
. ./test-lib.sh
###########################################################
# check the tag.sig file, expecting verify_tag() to fail,
# and checking that the error message matches the pattern
# given in the expect.pat file.
check_verify_failure () {
test_expect_success \
"$1" \
'git-mktag <tag.sig 2>message ||
egrep -q -f expect.pat message'
}
###########################################################
# first create a commit, so we have a valid object/type
# for the tag.
echo Hello >A
git-update-index --add A
git-commit -m "Initial commit"
head=$(git-rev-parse --verify HEAD)
############################################################
# 1. length check
cat >tag.sig <<EOF
too short for a tag
EOF
cat >expect.pat <<EOF
^error: .*size wrong.*$
EOF
check_verify_failure 'Tag object length check'
############################################################
# 2. object line label check
cat >tag.sig <<EOF
xxxxxx 139e9b33986b1c2670fff52c5067603117b3e895
type tag
tag mytag
EOF
cat >expect.pat <<EOF
^error: char0: .*"object "$
EOF
check_verify_failure '"object" line label check'
############################################################
# 3. object line SHA1 check
cat >tag.sig <<EOF
object zz9e9b33986b1c2670fff52c5067603117b3e895
type tag
tag mytag
EOF
cat >expect.pat <<EOF
^error: char7: .*SHA1 hash$
EOF
check_verify_failure '"object" line SHA1 check'
############################################################
# 4. type line label check
cat >tag.sig <<EOF
object 779e9b33986b1c2670fff52c5067603117b3e895
xxxx tag
tag mytag
EOF
cat >expect.pat <<EOF
^error: char47: .*"[\]ntype "$
EOF
check_verify_failure '"type" line label check'
############################################################
# 5. type line eol check
echo "object 779e9b33986b1c2670fff52c5067603117b3e895" >tag.sig
echo -n "type tagsssssssssssssssssssssssssssssss" >>tag.sig
cat >expect.pat <<EOF
^error: char48: .*"[\]n"$
EOF
check_verify_failure '"type" line eol check'
############################################################
# 6. tag line label check #1
cat >tag.sig <<EOF
object 779e9b33986b1c2670fff52c5067603117b3e895
type tag
xxx mytag
EOF
cat >expect.pat <<EOF
^error: char57: no "tag " found$
EOF
check_verify_failure '"tag" line label check #1'
############################################################
# 7. tag line label check #2
cat >tag.sig <<EOF
object 779e9b33986b1c2670fff52c5067603117b3e895
type taggggggggggggggggggggggggggggggg
tag
EOF
cat >expect.pat <<EOF
^error: char87: no "tag " found$
EOF
check_verify_failure '"tag" line label check #2'
############################################################
# 8. type line type-name length check
cat >tag.sig <<EOF
object 779e9b33986b1c2670fff52c5067603117b3e895
type taggggggggggggggggggggggggggggggg
tag mytag
EOF
cat >expect.pat <<EOF
^error: char53: type too long$
EOF
check_verify_failure '"type" line type-name length check'
############################################################
# 9. verify object (SHA1/type) check
cat >tag.sig <<EOF
object 779e9b33986b1c2670fff52c5067603117b3e895
type tagggg
tag mytag
EOF
cat >expect.pat <<EOF
^error: char7: could not verify object.*$
EOF
check_verify_failure 'verify object (SHA1/type) check'
############################################################
# 10. verify tag-name check
cat >tag.sig <<EOF
object $head
type commit
tag my tag
EOF
cat >expect.pat <<EOF
^error: char67: could not verify tag name$
EOF
check_verify_failure 'verify tag-name check'
############################################################
# 11. tagger line lable check #1
cat >tag.sig <<EOF
object $head
type commit
tag mytag
EOF
cat >expect.pat <<EOF
^error: char70: could not find "tagger"$
EOF
check_verify_failure '"tagger" line label check #1'
############################################################
# 12. tagger line lable check #2
cat >tag.sig <<EOF
object $head
type commit
tag mytag
tagger
EOF
cat >expect.pat <<EOF
^error: char70: could not find "tagger"$
EOF
check_verify_failure '"tagger" line label check #2'
############################################################
# 13. create valid tag
cat >tag.sig <<EOF
object $head
type commit
tag mytag
tagger another@example.com
EOF
test_expect_success \
'create valid tag' \
'git-mktag <tag.sig >.git/refs/tags/mytag 2>message'
############################################################
# 14. check mytag
test_expect_success \
'check mytag' \
'git-tag -l | grep mytag'
test_done

View File

@ -88,7 +88,7 @@ test_expect_success setup '
+*+ [initial] Initial
EOF
V=`git version | sed -e 's/^git version //'`
V=`git version | sed -e 's/^git version //' -e 's/\./\\./g'`
while read cmd
do
case "$cmd" in
@ -103,7 +103,9 @@ do
test_expect_success "git $cmd" '
{
echo "\$ git $cmd"
git $cmd | sed -e "s/$V/g-i-t--v-e-r-s-i-o-n/"
git $cmd |
sed -e "s/^\\(-*\\)$V\\(-*\\)\$/\\1g-i-t--v-e-r-s-i-o-n\2/" \
-e "s/^\\( *boundary=\"-*\\)$V\\(-*\\)\"\$/\\1g-i-t--v-e-r-s-i-o-n\2\"/"
echo "\$"
} >"$actual" &&
if test -f "$expect"

49
t/t4115-apply-symlink.sh Executable file
View File

@ -0,0 +1,49 @@
#!/bin/sh
#
# Copyright (c) 2005 Junio C Hamano
#
test_description='git-apply symlinks and partial files
'
. ./test-lib.sh
test_expect_success setup '
ln -s path1/path2/path3/path4/path5 link1 &&
git add link? &&
git commit -m initial &&
git branch side &&
rm -f link? &&
ln -s htap6 link1 &&
git update-index link? &&
git commit -m second &&
git diff-tree -p HEAD^ HEAD >patch &&
git apply --stat --summary patch
'
test_expect_success 'apply symlink patch' '
git checkout side &&
git apply patch &&
git diff-files -p >patched &&
diff -u patch patched
'
test_expect_success 'apply --index symlink patch' '
git checkout -f side &&
git apply --index patch &&
git diff-index --cached -p HEAD >patched &&
diff -u patch patched
'
test_done

85
t/t7002-grep.sh Executable file
View File

@ -0,0 +1,85 @@
#!/bin/sh
#
# Copyright (c) 2006 Junio C Hamano
#
test_description='git grep -w
'
. ./test-lib.sh
test_expect_success setup '
{
echo foo mmap bar
echo foo_mmap bar
echo foo_mmap bar mmap
echo foo mmap bar_mmap
echo foo_mmap bar mmap baz
} >file &&
echo x x xx x >x &&
echo y yy >y &&
echo zzz > z &&
git add file x y z &&
git commit -m initial
'
for H in HEAD ''
do
case "$H" in
HEAD) HC='HEAD:' L='HEAD' ;;
'') HC= L='in working tree' ;;
esac
test_expect_success "grep -w $L" '
{
echo ${HC}file:1:foo mmap bar
echo ${HC}file:3:foo_mmap bar mmap
echo ${HC}file:4:foo mmap bar_mmap
echo ${HC}file:5:foo_mmap bar mmap baz
} >expected &&
git grep -n -w -e mmap $H >actual &&
diff expected actual
'
test_expect_success "grep -w $L (x)" '
{
echo ${HC}x:1:x x xx x
} >expected &&
git grep -n -w -e "x xx* x" $H >actual &&
diff expected actual
'
test_expect_success "grep -w $L (y-1)" '
{
echo ${HC}y:1:y yy
} >expected &&
git grep -n -w -e "^y" $H >actual &&
diff expected actual
'
test_expect_success "grep -w $L (y-2)" '
: >expected &&
if git grep -n -w -e "^y y" $H >actual
then
echo should not have matched
cat actual
false
else
diff expected actual
fi
'
test_expect_success "grep -w $L (z)" '
: >expected &&
if git grep -n -w -e "^z" $H >actual
then
echo should not have matched
cat actual
false
else
diff expected actual
fi
'
done
test_done

View File

@ -170,7 +170,7 @@ then
test -L $SVN_TREE/exec-2.sh"
name='modify a symlink to become a file'
git help > help || true
echo git help > help || true
rm exec-2.sh
cp help exec-2.sh
git update-index exec-2.sh
@ -217,10 +217,10 @@ name='check imported tree checksums expected tree checksums'
rm -f expected
if test "$have_utf8" = t
then
echo tree f735671b89a7eb30cab1d8597de35bd4271ab813 > expected
echo tree bf522353586b1b883488f2bc73dab0d9f774b9a9 > expected
fi
cat >> expected <<\EOF
tree 4b9af72bb861eaed053854ec502cf7df72618f0f
tree 83654bb36f019ae4fe77a0171f81075972087624
tree 031b8d557afc6fea52894eaebb45bec52f1ba6d1
tree 0b094cbff17168f24c302e297f55bfac65eb8bd3
tree d667270a1f7b109f5eb3aaea21ede14b56bfdd6e
@ -231,4 +231,3 @@ EOF
test_expect_success "$name" "diff -u a expected"
test_done

View File

@ -6,11 +6,9 @@ prefix ?= $(HOME)
template_dir ?= $(prefix)/share/git-core/templates/
# DESTDIR=
# Shell quote;
# Result of this needs to be placed inside ''
shq = $(subst ','\'',$(1))
# This has surrounding ''
shellquote = '$(call shq,$(1))'
# Shell quote (do not use $(call) to accomodate ancient setups);
DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
template_dir_SQ = $(subst ','\'',$(template_dir))
all: boilerplates.made custom
@ -43,6 +41,6 @@ clean:
rm -rf blt boilerplates.made
install: all
$(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(template_dir))
$(INSTALL) -d -m755 '$(DESTDIR_SQ)$(template_dir_SQ)'
(cd blt && $(TAR) cf - .) | \
(cd $(call shellquote,$(DESTDIR)$(template_dir)) && $(TAR) xf -)
(cd '$(DESTDIR_SQ)$(template_dir_SQ)' && $(TAR) xf -)

View File

@ -1,43 +1,60 @@
#include "cache.h"
#include "pack.h"
static int verify_one_pack(char *arg, int verbose)
static int verify_one_pack(const char *path, int verbose)
{
int len = strlen(arg);
struct packed_git *g;
while (1) {
/* Should name foo.idx, but foo.pack may be named;
* convert it to foo.idx
*/
if (!strcmp(arg + len - 5, ".pack")) {
strcpy(arg + len - 5, ".idx");
len--;
}
/* Should name foo.idx now */
if ((g = add_packed_git(arg, len, 1)))
break;
/* No? did you name just foo? */
char arg[PATH_MAX];
int len;
struct packed_git *pack;
int err;
len = strlcpy(arg, path, PATH_MAX);
if (len >= PATH_MAX)
return error("name too long: %s", path);
/*
* In addition to "foo.idx" we accept "foo.pack" and "foo";
* normalize these forms to "foo.idx" for add_packed_git().
*/
if (has_extension(arg, ".pack")) {
strcpy(arg + len - 5, ".idx");
len--;
} else if (!has_extension(arg, ".idx")) {
if (len + 4 >= PATH_MAX)
return error("name too long: %s.idx", arg);
strcpy(arg + len, ".idx");
len += 4;
if ((g = add_packed_git(arg, len, 1)))
break;
return error("packfile %s not found.", arg);
}
return verify_pack(g, verbose);
/*
* add_packed_git() uses our buffer (containing "foo.idx") to
* build the pack filename ("foo.pack"). Make sure it fits.
*/
if (len + 1 >= PATH_MAX) {
arg[len - 4] = '\0';
return error("name too long: %s.pack", arg);
}
pack = add_packed_git(arg, len, 1);
if (!pack)
return error("packfile %s not found.", arg);
err = verify_pack(pack, verbose);
free(pack);
return err;
}
static const char verify_pack_usage[] = "git-verify-pack [-v] <pack>...";
int main(int ac, char **av)
{
int errs = 0;
int err = 0;
int verbose = 0;
int no_more_options = 0;
int nothing_done = 1;
while (1 < ac) {
char path[PATH_MAX];
if (!no_more_options && av[1][0] == '-') {
if (!strcmp("-v", av[1]))
verbose = 1;
@ -47,11 +64,15 @@ int main(int ac, char **av)
usage(verify_pack_usage);
}
else {
strcpy(path, av[1]);
if (verify_one_pack(path, verbose))
errs++;
if (verify_one_pack(av[1], verbose))
err = 1;
nothing_done = 0;
}
ac--; av++;
}
return !!errs;
if (nothing_done)
usage(verify_pack_usage);
return err;
}