Merge branch 'master' of git://repo.or.cz/alt-git

This commit is contained in:
Johannes Sixt
2008-07-26 22:17:08 +02:00
70 changed files with 963 additions and 518 deletions

View File

@@ -358,7 +358,8 @@ core.whitespace::
A comma separated list of common whitespace problems to
notice. 'git-diff' will use `color.diff.whitespace` to
highlight them, and 'git-apply --whitespace=error' will
consider them as errors:
consider them as errors. You can prefix `-` to disable
any of them (e.g. `-trailing-space`):
+
* `trailing-space` treats trailing whitespaces at the end of the line
as an error (enabled by default).

View File

@@ -9,7 +9,7 @@ SYNOPSIS
--------
[verse]
'git checkout' [-q] [-f] [[--track | --no-track] -b <new_branch> [-l]] [-m] [<branch>]
'git checkout' [<tree-ish>] <paths>...
'git checkout' [<tree-ish>] [--] <paths>...
DESCRIPTION
-----------

View File

@@ -87,8 +87,8 @@ then the cloned repository will become corrupt.
--quiet::
-q::
Operate quietly. This flag is passed to "rsync" and
'git-fetch-pack' commands when given.
Operate quietly. This flag is also passed to the `rsync'
command when given.
--no-checkout::
-n::
@@ -113,9 +113,8 @@ then the cloned repository will become corrupt.
--upload-pack <upload-pack>::
-u <upload-pack>::
When given, and the repository to clone from is handled
by 'git-fetch-pack', `--exec=<upload-pack>` is passed to
the command to specify non-default path for the command
When given, and the repository to clone from is accessed
via ssh, this specifies a non-default path for the command
run on the other end.
--template=<template_directory>::

View File

@@ -93,11 +93,11 @@ include::pretty-options.txt[]
This flag changes the way a merge commit patch is displayed,
in a similar way to the '-c' option. It implies the '-c'
and '-p' options and further compresses the patch output
by omitting hunks that show differences from only one
parent, or show the same change from all but one parent
for an Octopus merge. When this optimization makes all
hunks disappear, the commit itself and the commit log
message is not shown, just like in any other "empty diff" case.
by omitting uninteresting hunks whose the contents in the parents
have only two variants and the merge result picks one of them
without modification. When all hunks are uninteresting, the commit
itself and the commit log message is not shown, just like in any other
"empty diff" case.
--always::
Show the commit itself and the commit log message even

View File

@@ -191,7 +191,7 @@ Thus you may instead want to use `rm -f filename` as the script.
A significantly faster version:
--------------------------------------------------------------------------
git filter-branch --index-filter 'git update-index --remove filename' HEAD
git filter-branch --index-filter 'git rm --cached filename' HEAD
--------------------------------------------------------------------------
Now, you will get the rewritten history saved in HEAD.

View File

@@ -37,7 +37,7 @@ its working state.
'clear'::
This resets the metadata used by rerere if a merge resolution is to be
is aborted. Calling 'git-am --skip' or 'git-rebase [--skip|--abort]'
aborted. Calling 'git-am [--skip|--abort]' or 'git-rebase [--skip|--abort]'
will automatically invoke this command.
'diff'::

View File

@@ -9,7 +9,8 @@ git-tag - Create, list, delete or verify a tag object signed with GPG
SYNOPSIS
--------
[verse]
'git tag' [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] <name> [<head>]
'git tag' [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>]
<name> [<commit> | <object>]
'git tag' -d <name>...
'git tag' [-n[<num>]] -l [<pattern>]
'git tag' -v <name>...

View File

@@ -112,9 +112,9 @@ options may be given. See linkgit:git-diff-files[1] for more options.
--cc::
This flag implies the '-c' options and further compresses the
patch output by omitting hunks that show differences from only
one parent, or show the same change from all but one parent for
an Octopus merge.
patch output by omitting uninteresting hunks whose contents in
the parents have only two variants and the merge result picks
one of them without modification.
-r::

View File

@@ -41,7 +41,7 @@ memset(&list, 0, sizeof(struct string_list));
string_list_append("foo", &list);
string_list_append("bar", &list);
for (i = 0; i < list.nr; i++)
printf("%s\n", list.items[i].path)
printf("%s\n", list.items[i].string)
----
NOTE: It is more efficient to build an unsorted list and sort it
@@ -113,7 +113,7 @@ Data structures
* `struct string_list_item`
Represents an item of the list. The `path` member is a pointer to the
Represents an item of the list. The `string` member is a pointer to the
string, and you may use the `util` member for any purpose, if you want.
* `struct string_list`

View File

@@ -170,6 +170,16 @@ ALL_CFLAGS = $(CFLAGS)
ALL_LDFLAGS = $(LDFLAGS)
STRIP ?= strip
# Among the variables below, these:
# gitexecdir
# template_dir
# htmldir
# ETC_GITCONFIG (but not sysconfdir)
# can be specified as a relative path ../some/where/else (which must begin
# with ../); this is interpreted as relative to $(bindir) and "git" at
# runtime figures out where they are based on the path to the executable.
# This can help installing the suite in a relocatable way.
prefix = $(HOME)
bindir = $(prefix)/bin
mandir = $(prefix)/share/man
@@ -205,7 +215,7 @@ GITWEB_FAVICON = git-favicon.png
GITWEB_SITE_HEADER =
GITWEB_SITE_FOOTER =
export prefix bindir gitexecdir sharedir htmldir sysconfdir
export prefix bindir sharedir htmldir sysconfdir
CC = gcc
AR = ar
@@ -283,7 +293,6 @@ PROGRAMS += git-pack-redundant$X
PROGRAMS += git-patch-id$X
PROGRAMS += git-receive-pack$X
PROGRAMS += git-send-pack$X
PROGRAMS += git-shell$X
PROGRAMS += git-show-index$X
PROGRAMS += git-unpack-file$X
PROGRAMS += git-update-server-info$X
@@ -410,6 +419,7 @@ LIB_OBJS += diff-no-index.o
LIB_OBJS += diff-lib.o
LIB_OBJS += diff.o
LIB_OBJS += dir.o
LIB_OBJS += editor.o
LIB_OBJS += entry.o
LIB_OBJS += environment.o
LIB_OBJS += exec_cmd.o
@@ -745,6 +755,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
COMPAT_OBJS += compat/mingw.o compat/fnmatch.o compat/regex.o compat/winansi.o
EXTLIBS += -lws2_32
X = .exe
gitexecdir = ../libexec/git-core
template_dir = ../share/git-core/templates/
ETC_GITCONFIG = ../etc/gitconfig
endif
@@ -811,6 +822,7 @@ EXTLIBS += -lz
ifndef NO_POSIX_ONLY_PROGRAMS
PROGRAMS += git-daemon$X
PROGRAMS += git-imap-send$X
PROGRAMS += git-shell$X
endif
ifndef NO_OPENSSL
OPENSSL_LIBSSL = -lssl
@@ -1255,8 +1267,12 @@ GIT-CFLAGS: .FORCE-GIT-CFLAGS
echo "$$FLAGS" >GIT-CFLAGS; \
fi
# We need to apply sq twice, once to protect from the shell
# that runs GIT-BUILD-OPTIONS, and then again to protect it
# and the first level quoting from the shell that runs "echo".
GIT-BUILD-OPTIONS: .FORCE-GIT-BUILD-OPTIONS
@echo SHELL_PATH=\''$(SHELL_PATH_SQ)'\' >$@
@echo SHELL_PATH=\''$(subst ','\'',$(SHELL_PATH_SQ))'\' >$@
@echo TAR=\''$(subst ','\'',$(subst ','\'',$(TAR)))'\' >>$@
### Detect Tck/Tk interpreter path changes
ifndef NO_TCLTK
@@ -1310,35 +1326,44 @@ remove-dashes:
### Installation rules
ifeq ($(firstword $(subst /, ,$(template_dir))),..)
template_instdir = $(gitexecdir)/$(template_dir)
template_instdir = $(bindir)/$(template_dir)
else
template_instdir = $(template_dir)
endif
export template_instdir
ifeq ($(firstword $(subst /, ,$(gitexecdir))),..)
gitexec_instdir = $(bindir)/$(gitexecdir)
else
gitexec_instdir = $(gitexecdir)
endif
gitexec_instdir_SQ = $(subst ','\'',$(gitexec_instdir))
export gitexec_instdir
install: all
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(gitexecdir_SQ)'
$(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexecdir_SQ)'
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) git$X git-upload-pack$X git-receive-pack$X git-upload-archive$X '$(DESTDIR_SQ)$(bindir_SQ)'
$(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install
$(MAKE) -C perl prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' install
ifndef NO_TCLTK
$(MAKE) -C gitk-git install
$(MAKE) -C git-gui install
$(MAKE) -C git-gui gitexecdir='$(gitexec_instdir_SQ)' install
endif
if test 'z$(bindir_SQ)' != 'z$(gitexecdir_SQ)'; \
then \
ln -f '$(DESTDIR_SQ)$(bindir_SQ)/git$X' \
'$(DESTDIR_SQ)$(gitexecdir_SQ)/git$X' || \
cp '$(DESTDIR_SQ)$(bindir_SQ)/git$X' \
'$(DESTDIR_SQ)$(gitexecdir_SQ)/git$X'; \
fi
$(foreach p,$(BUILT_INS), $(RM) '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' && ln '$(DESTDIR_SQ)$(gitexecdir_SQ)/git$X' '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' ;)
ifneq (,$X)
$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), $(RM) '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p';)
$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), $(RM) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)/$p';)
endif
./check_bindir 'z$(bindir_SQ)' 'z$(gitexecdir_SQ)' '$(DESTDIR_SQ)$(bindir_SQ)/git-shell$X'
bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \
execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \
if test "z$$bindir" != "z$$execdir"; \
then \
ln -f "$$bindir/git$X" "$$execdir/git$X" || \
cp "$$bindir/git$X" "$$execdir/git$X"; \
fi && \
{ $(foreach p,$(BUILT_INS), $(RM) "$$execdir/$p" && ln "$$execdir/git$X" "$$execdir/$p" ;) } && \
$(RM) "$$execdir/git$X" && \
./check_bindir "z$$bindir" "z$$execdir" "$$bindir/git-add$X"
install-doc:
$(MAKE) -C Documentation install

View File

@@ -66,3 +66,39 @@ const char *make_absolute_path(const char *path)
return buf;
}
static const char *get_pwd_cwd(void)
{
static char cwd[PATH_MAX + 1];
char *pwd;
struct stat cwd_stat, pwd_stat;
if (getcwd(cwd, PATH_MAX) == NULL)
return NULL;
pwd = getenv("PWD");
if (pwd && strcmp(pwd, cwd)) {
stat(cwd, &cwd_stat);
if (!stat(pwd, &pwd_stat) &&
pwd_stat.st_dev == cwd_stat.st_dev &&
pwd_stat.st_ino == cwd_stat.st_ino) {
strlcpy(cwd, pwd, PATH_MAX);
}
}
return cwd;
}
const char *make_nonrelative_path(const char *path)
{
static char buf[PATH_MAX + 1];
if (is_absolute_path(path)) {
if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX)
die("Too long path: %.*s", 60, path);
} else {
const char *cwd = get_pwd_cwd();
if (!cwd)
die("Cannot determine the current working directory");
if (snprintf(buf, PATH_MAX, "%s/%s", cwd, path) >= PATH_MAX)
die("Too long path: %.*s", 60, path);
}
return buf;
}

159
archive.c
View File

@@ -1,8 +1,23 @@
#include "cache.h"
#include "commit.h"
#include "tree-walk.h"
#include "attr.h"
#include "archive.h"
static const char archive_usage[] = \
"git archive --format=<fmt> [--prefix=<prefix>/] [--verbose] [<extra>] <tree-ish> [path...]";
#define USES_ZLIB_COMPRESSION 1
const struct archiver {
const char *name;
write_archive_fn_t write_archive;
unsigned int flags;
} archivers[] = {
{ "tar", write_tar_archive },
{ "zip", write_zip_archive, USES_ZLIB_COMPRESSION },
};
static void format_subst(const struct commit *commit,
const char *src, size_t len,
struct strbuf *buf)
@@ -155,3 +170,147 @@ int write_archive_entries(struct archiver_args *args,
err = 0;
return err;
}
static const struct archiver *lookup_archiver(const char *name)
{
int i;
for (i = 0; i < ARRAY_SIZE(archivers); i++) {
if (!strcmp(name, archivers[i].name))
return &archivers[i];
}
return NULL;
}
static void parse_pathspec_arg(const char **pathspec,
struct archiver_args *ar_args)
{
ar_args->pathspec = get_pathspec(ar_args->base, pathspec);
}
static void parse_treeish_arg(const char **argv,
struct archiver_args *ar_args, const char *prefix)
{
const char *name = argv[0];
const unsigned char *commit_sha1;
time_t archive_time;
struct tree *tree;
const struct commit *commit;
unsigned char sha1[20];
if (get_sha1(name, sha1))
die("Not a valid object name");
commit = lookup_commit_reference_gently(sha1, 1);
if (commit) {
commit_sha1 = commit->object.sha1;
archive_time = commit->date;
} else {
commit_sha1 = NULL;
archive_time = time(NULL);
}
tree = parse_tree_indirect(sha1);
if (tree == NULL)
die("not a tree object");
if (prefix) {
unsigned char tree_sha1[20];
unsigned int mode;
int err;
err = get_tree_entry(tree->object.sha1, prefix,
tree_sha1, &mode);
if (err || !S_ISDIR(mode))
die("current working directory is untracked");
tree = parse_tree_indirect(tree_sha1);
}
ar_args->tree = tree;
ar_args->commit_sha1 = commit_sha1;
ar_args->commit = commit;
ar_args->time = archive_time;
}
static int parse_archive_args(int argc, const char **argv,
const struct archiver **ar, struct archiver_args *args)
{
const char *format = "tar";
const char *base = "";
int compression_level = -1;
int verbose = 0;
int i;
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
if (!strcmp(arg, "--list") || !strcmp(arg, "-l")) {
for (i = 0; i < ARRAY_SIZE(archivers); i++)
printf("%s\n", archivers[i].name);
exit(0);
}
if (!strcmp(arg, "--verbose") || !strcmp(arg, "-v")) {
verbose = 1;
continue;
}
if (!prefixcmp(arg, "--format=")) {
format = arg + 9;
continue;
}
if (!prefixcmp(arg, "--prefix=")) {
base = arg + 9;
continue;
}
if (!strcmp(arg, "--")) {
i++;
break;
}
if (arg[0] == '-' && isdigit(arg[1]) && arg[2] == '\0') {
compression_level = arg[1] - '0';
continue;
}
if (arg[0] == '-')
die("Unknown argument: %s", arg);
break;
}
/* We need at least one parameter -- tree-ish */
if (argc - 1 < i)
usage(archive_usage);
*ar = lookup_archiver(format);
if (!*ar)
die("Unknown archive format '%s'", format);
args->compression_level = Z_DEFAULT_COMPRESSION;
if (compression_level != -1) {
if ((*ar)->flags & USES_ZLIB_COMPRESSION)
args->compression_level = compression_level;
else {
die("Argument not supported for format '%s': -%d",
format, compression_level);
}
}
args->verbose = verbose;
args->base = base;
args->baselen = strlen(base);
return i;
}
int write_archive(int argc, const char **argv, const char *prefix,
int setup_prefix)
{
const struct archiver *ar = NULL;
struct archiver_args args;
int tree_idx;
tree_idx = parse_archive_args(argc, argv, &ar, &args);
if (setup_prefix && prefix == NULL)
prefix = setup_git_directory();
argv += tree_idx;
parse_treeish_arg(argv, &args, prefix);
parse_pathspec_arg(argv + 1, &args);
return ar->write_archive(&args);
}

View File

@@ -1,9 +1,6 @@
#ifndef ARCHIVE_H
#define ARCHIVE_H
#define MAX_EXTRA_ARGS 32
#define MAX_ARGS (MAX_EXTRA_ARGS + 32)
struct archiver_args {
const char *base;
size_t baselen;
@@ -20,20 +17,6 @@ typedef int (*write_archive_fn_t)(struct archiver_args *);
typedef int (*write_archive_entry_fn_t)(struct archiver_args *args, const unsigned char *sha1, const char *path, size_t pathlen, unsigned int mode, void *buffer, unsigned long size);
struct archiver {
const char *name;
write_archive_fn_t write_archive;
unsigned int flags;
};
extern int parse_archive_args(int argc, const char **argv, const struct archiver **ar, struct archiver_args *args);
extern void parse_treeish_arg(const char **treeish,
struct archiver_args *ar_args,
const char *prefix);
extern void parse_pathspec_arg(const char **pathspec,
struct archiver_args *args);
/*
* Archive-format specific backends.
*/
@@ -41,5 +24,6 @@ extern int write_tar_archive(struct archiver_args *);
extern int write_zip_archive(struct archiver_args *);
extern int write_archive_entries(struct archiver_args *args, write_archive_entry_fn_t write_entry);
extern int write_archive(int argc, const char **argv, const char *prefix, int setup_prefix);
#endif /* ARCHIVE_H */

View File

@@ -5,21 +5,9 @@
#include "cache.h"
#include "builtin.h"
#include "archive.h"
#include "commit.h"
#include "tree-walk.h"
#include "pkt-line.h"
#include "sideband.h"
static const char archive_usage[] = \
"git archive --format=<fmt> [--prefix=<prefix>/] [--verbose] [<extra>] <tree-ish> [path...]";
#define USES_ZLIB_COMPRESSION 1
const struct archiver archivers[] = {
{ "tar", write_tar_archive },
{ "zip", write_zip_archive, USES_ZLIB_COMPRESSION },
};
static int run_remote_archiver(const char *remote, int argc,
const char **argv)
{
@@ -27,7 +15,7 @@ static int run_remote_archiver(const char *remote, int argc,
int fd[2], i, len, rv;
struct child_process *conn;
const char *exec = "git-upload-archive";
int exec_at = 0;
int exec_at = 0, exec_value_at = 0;
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
@@ -36,7 +24,14 @@ static int run_remote_archiver(const char *remote, int argc,
die("multiple --exec specified");
exec = arg + 7;
exec_at = i;
break;
} else if (!strcmp(arg, "--exec")) {
if (exec_at)
die("multiple --exec specified");
if (i + 1 >= argc)
die("option --exec requires a value");
exec = argv[i + 1];
exec_at = i;
exec_value_at = ++i;
}
}
@@ -44,7 +39,7 @@ static int run_remote_archiver(const char *remote, int argc,
conn = git_connect(fd, url, exec, 0);
for (i = 1; i < argc; i++) {
if (i == exec_at)
if (i == exec_at || i == exec_value_at)
continue;
packet_write(fd[1], "argument %s\n", argv[i]);
}
@@ -74,131 +69,6 @@ static int run_remote_archiver(const char *remote, int argc,
return !!rv;
}
static const struct archiver *lookup_archiver(const char *name)
{
int i;
for (i = 0; i < ARRAY_SIZE(archivers); i++) {
if (!strcmp(name, archivers[i].name))
return &archivers[i];
}
return NULL;
}
void parse_pathspec_arg(const char **pathspec, struct archiver_args *ar_args)
{
ar_args->pathspec = get_pathspec(ar_args->base, pathspec);
}
void parse_treeish_arg(const char **argv, struct archiver_args *ar_args,
const char *prefix)
{
const char *name = argv[0];
const unsigned char *commit_sha1;
time_t archive_time;
struct tree *tree;
const struct commit *commit;
unsigned char sha1[20];
if (get_sha1(name, sha1))
die("Not a valid object name");
commit = lookup_commit_reference_gently(sha1, 1);
if (commit) {
commit_sha1 = commit->object.sha1;
archive_time = commit->date;
} else {
commit_sha1 = NULL;
archive_time = time(NULL);
}
tree = parse_tree_indirect(sha1);
if (tree == NULL)
die("not a tree object");
if (prefix) {
unsigned char tree_sha1[20];
unsigned int mode;
int err;
err = get_tree_entry(tree->object.sha1, prefix,
tree_sha1, &mode);
if (err || !S_ISDIR(mode))
die("current working directory is untracked");
tree = parse_tree_indirect(tree_sha1);
}
ar_args->tree = tree;
ar_args->commit_sha1 = commit_sha1;
ar_args->commit = commit;
ar_args->time = archive_time;
}
int parse_archive_args(int argc, const char **argv, const struct archiver **ar,
struct archiver_args *args)
{
const char *format = "tar";
const char *base = "";
int compression_level = -1;
int verbose = 0;
int i;
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
if (!strcmp(arg, "--list") || !strcmp(arg, "-l")) {
for (i = 0; i < ARRAY_SIZE(archivers); i++)
printf("%s\n", archivers[i].name);
exit(0);
}
if (!strcmp(arg, "--verbose") || !strcmp(arg, "-v")) {
verbose = 1;
continue;
}
if (!prefixcmp(arg, "--format=")) {
format = arg + 9;
continue;
}
if (!prefixcmp(arg, "--prefix=")) {
base = arg + 9;
continue;
}
if (!strcmp(arg, "--")) {
i++;
break;
}
if (arg[0] == '-' && isdigit(arg[1]) && arg[2] == '\0') {
compression_level = arg[1] - '0';
continue;
}
if (arg[0] == '-')
die("Unknown argument: %s", arg);
break;
}
/* We need at least one parameter -- tree-ish */
if (argc - 1 < i)
usage(archive_usage);
*ar = lookup_archiver(format);
if (!*ar)
die("Unknown archive format '%s'", format);
args->compression_level = Z_DEFAULT_COMPRESSION;
if (compression_level != -1) {
if ((*ar)->flags & USES_ZLIB_COMPRESSION)
args->compression_level = compression_level;
else {
die("Argument not supported for format '%s': -%d",
format, compression_level);
}
}
args->verbose = verbose;
args->base = base;
args->baselen = strlen(base);
return i;
}
static const char *extract_remote_arg(int *ac, const char **av)
{
int ix, iy, cnt = *ac;
@@ -215,6 +85,13 @@ static const char *extract_remote_arg(int *ac, const char **av)
die("Multiple --remote specified");
remote = arg + 9;
continue;
} else if (!strcmp(arg, "--remote")) {
if (remote)
die("Multiple --remote specified");
if (++ix >= cnt)
die("option --remote requires a value");
remote = av[ix];
continue;
}
if (arg[0] != '-')
no_more_options = 1;
@@ -232,9 +109,6 @@ static const char *extract_remote_arg(int *ac, const char **av)
int cmd_archive(int argc, const char **argv, const char *prefix)
{
const struct archiver *ar = NULL;
struct archiver_args args;
int tree_idx;
const char *remote = NULL;
remote = extract_remote_arg(&argc, argv);
@@ -243,13 +117,5 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
tree_idx = parse_archive_args(argc, argv, &ar, &args);
if (prefix == NULL)
prefix = setup_git_directory();
argv += tree_idx;
parse_treeish_arg(argv, &args, prefix);
parse_pathspec_arg(argv + 1, &args);
return ar->write_archive(&args);
return write_archive(argc, argv, prefix, 1);
}

View File

@@ -13,6 +13,8 @@
#include "remote.h"
#include "parse-options.h"
#include "branch.h"
#include "diff.h"
#include "revision.h"
static const char * const builtin_branch_usage[] = {
"git branch [options] [-r | -a] [--merged | --no-merged]",
@@ -22,10 +24,8 @@ static const char * const builtin_branch_usage[] = {
NULL
};
#define REF_UNKNOWN_TYPE 0x00
#define REF_LOCAL_BRANCH 0x01
#define REF_REMOTE_BRANCH 0x02
#define REF_TAG 0x04
static const char *head;
static unsigned char head_sha1[20];
@@ -181,25 +181,21 @@ static int delete_branches(int argc, const char **argv, int force, int kinds)
struct ref_item {
char *name;
unsigned int kind;
unsigned char sha1[20];
struct commit *commit;
};
struct ref_list {
struct rev_info revs;
int index, alloc, maxwidth;
struct ref_item *list;
struct commit_list *with_commit;
int kinds;
};
static int has_commit(const unsigned char *sha1, struct commit_list *with_commit)
static int has_commit(struct commit *commit, struct commit_list *with_commit)
{
struct commit *commit;
if (!with_commit)
return 1;
commit = lookup_commit_reference_gently(sha1, 1);
if (!commit)
return 0;
while (with_commit) {
struct commit *other;
@@ -215,7 +211,8 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
{
struct ref_list *ref_list = (struct ref_list*)(cb_data);
struct ref_item *newitem;
int kind = REF_UNKNOWN_TYPE;
struct commit *commit;
int kind;
int len;
static struct commit_list branch;
@@ -226,13 +223,15 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
} else if (!prefixcmp(refname, "refs/remotes/")) {
kind = REF_REMOTE_BRANCH;
refname += 13;
} else if (!prefixcmp(refname, "refs/tags/")) {
kind = REF_TAG;
refname += 10;
}
} else
return 0;
commit = lookup_commit_reference_gently(sha1, 1);
if (!commit)
return error("branch '%s' does not point at a commit", refname);
/* Filter with with_commit if specified */
if (!has_commit(sha1, ref_list->with_commit))
if (!has_commit(commit, ref_list->with_commit))
return 0;
/* Don't add types the caller doesn't want */
@@ -243,12 +242,8 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
branch.item = lookup_commit_reference_gently(sha1, 1);
if (!branch.item)
die("Unable to lookup tip of branch %s", refname);
if (merge_filter == SHOW_NOT_MERGED &&
has_commit(merge_filter_ref, &branch))
return 0;
if (merge_filter == SHOW_MERGED &&
!has_commit(merge_filter_ref, &branch))
return 0;
add_pending_object(&ref_list->revs,
(struct object *)branch.item, refname);
}
/* Resize buffer */
@@ -262,7 +257,7 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
newitem = &(ref_list->list[ref_list->index++]);
newitem->name = xstrdup(refname);
newitem->kind = kind;
hashcpy(newitem->sha1, sha1);
newitem->commit = commit;
len = strlen(newitem->name);
if (len > ref_list->maxwidth)
ref_list->maxwidth = len;
@@ -309,7 +304,13 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
{
char c;
int color;
struct commit *commit;
struct commit *commit = item->commit;
if (merge_filter != NO_FILTER) {
int is_merged = !!(item->commit->object.flags & UNINTERESTING);
if (is_merged != (merge_filter == SHOW_MERGED))
return;
}
switch (item->kind) {
case REF_LOCAL_BRANCH:
@@ -337,7 +338,7 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
strbuf_init(&subject, 0);
stat[0] = '\0';
commit = lookup_commit(item->sha1);
commit = item->commit;
if (commit && !parse_commit(commit)) {
pretty_print_commit(CMIT_FMT_ONELINE, commit,
&subject, 0, NULL, NULL, 0, 0);
@@ -350,7 +351,7 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
printf("%c %s%-*s%s %s %s%s\n", c, branch_get_color(color),
maxwidth, item->name,
branch_get_color(COLOR_BRANCH_RESET),
find_unique_abbrev(item->sha1, abbrev),
find_unique_abbrev(item->commit->object.sha1, abbrev),
stat, sub);
strbuf_release(&subject);
} else {
@@ -363,22 +364,34 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev, str
{
int i;
struct ref_list ref_list;
struct commit *head_commit = lookup_commit_reference_gently(head_sha1, 1);
memset(&ref_list, 0, sizeof(ref_list));
ref_list.kinds = kinds;
ref_list.with_commit = with_commit;
if (merge_filter != NO_FILTER)
init_revisions(&ref_list.revs, NULL);
for_each_ref(append_ref, &ref_list);
if (merge_filter != NO_FILTER) {
struct commit *filter;
filter = lookup_commit_reference_gently(merge_filter_ref, 0);
filter->object.flags |= UNINTERESTING;
add_pending_object(&ref_list.revs,
(struct object *) filter, "");
ref_list.revs.limited = 1;
prepare_revision_walk(&ref_list.revs);
}
qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);
detached = (detached && (kinds & REF_LOCAL_BRANCH));
if (detached && has_commit(head_sha1, with_commit)) {
if (detached && head_commit && has_commit(head_commit, with_commit)) {
struct ref_item item;
item.name = xstrdup("(no branch)");
item.kind = REF_LOCAL_BRANCH;
hashcpy(item.sha1, head_sha1);
item.commit = head_commit;
if (strlen(item.name) > ref_list.maxwidth)
ref_list.maxwidth = strlen(item.name);
ref_list.maxwidth = strlen(item.name);
print_ref_item(&item, ref_list.maxwidth, verbose, abbrev, 1);
free(item.name);
}

View File

@@ -430,6 +430,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
OPT_BOOLEAN('m', NULL, &opts.merge, "merge"),
OPT_END(),
};
int has_dash_dash;
memset(&opts, 0, sizeof(opts));
memset(&new, 0, sizeof(new));
@@ -438,12 +439,57 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
opts.track = git_branch_track;
argc = parse_options(argc, argv, options, checkout_usage, 0);
argc = parse_options(argc, argv, options, checkout_usage,
PARSE_OPT_KEEP_DASHDASH);
if (!opts.new_branch && (opts.track != git_branch_track))
die("git checkout: --track and --no-track require -b");
if (opts.force && opts.merge)
die("git checkout: -f and -m are incompatible");
/*
* case 1: git checkout <ref> -- [<paths>]
*
* <ref> must be a valid tree, everything after the '--' must be
* a path.
*
* case 2: git checkout -- [<paths>]
*
* everything after the '--' must be paths.
*
* case 3: git checkout <something> [<paths>]
*
* With no paths, if <something> is a commit, that is to
* switch to the branch or detach HEAD at it.
*
* Otherwise <something> shall not be ambiguous.
* - If it's *only* a reference, treat it like case (1).
* - If it's only a path, treat it like case (2).
* - else: fail.
*
*/
if (argc) {
if (!strcmp(argv[0], "--")) { /* case (2) */
argv++;
argc--;
goto no_reference;
}
arg = argv[0];
if (get_sha1(arg, rev))
;
else if ((new.commit = lookup_commit_reference_gently(rev, 1))) {
has_dash_dash = (argc > 1) && !strcmp(argv[1], "--");
if (get_sha1(arg, rev)) {
if (has_dash_dash) /* case (1) */
die("invalid reference: %s", arg);
goto no_reference; /* case (3 -> 2) */
}
/* we can't end up being in (2) anymore, eat the argument */
argv++;
argc--;
if ((new.commit = lookup_commit_reference_gently(rev, 1))) {
new.name = arg;
setup_branch_path(&new);
if (resolve_ref(new.path, rev, 1, NULL))
@@ -452,25 +498,28 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
new.path = NULL;
parse_commit(new.commit);
source_tree = new.commit->tree;
argv++;
argc--;
} else if ((source_tree = parse_tree_indirect(rev))) {
} else
source_tree = parse_tree_indirect(rev);
if (!source_tree) /* case (1): want a tree */
die("reference is not a tree: %s", arg);
if (!has_dash_dash) {/* case (3 -> 1) */
/*
* Do not complain the most common case
* git checkout branch
* even if there happen to be a file called 'branch';
* it would be extremely annoying.
*/
if (argc)
verify_non_filename(NULL, arg);
}
else {
argv++;
argc--;
}
}
if (argc && !strcmp(argv[0], "--")) {
argv++;
argc--;
}
if (!opts.new_branch && (opts.track != git_branch_track))
die("git checkout: --track and --no-track require -b");
if (opts.force && opts.merge)
die("git checkout: -f and -m are incompatible");
no_reference:
if (argc) {
const char **pathspec = get_pathspec(prefix, argv);

View File

@@ -480,6 +480,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
if (option_quiet)
transport->verbose = -1;
if (option_upload_pack)
transport_set_option(transport, TRANS_OPT_UPLOADPACK,
option_upload_pack);
refs = transport_get_remote_refs(transport);
transport_fetch_refs(transport, refs);
}

View File

@@ -68,8 +68,8 @@ static enum {
static char *cleanup_arg;
static int use_editor = 1, initial_commit, in_merge;
const char *only_include_assumed;
struct strbuf message;
static const char *only_include_assumed;
static struct strbuf message;
static int opt_parse_m(const struct option *opt, const char *arg, int unset)
{
@@ -78,8 +78,7 @@ static int opt_parse_m(const struct option *opt, const char *arg, int unset)
strbuf_setlen(buf, 0);
else {
strbuf_addstr(buf, arg);
strbuf_addch(buf, '\n');
strbuf_addch(buf, '\n');
strbuf_addstr(buf, "\n\n");
}
return 0;
}
@@ -647,7 +646,11 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
char index[PATH_MAX];
const char *env[2] = { index, NULL };
snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
launch_editor(git_path(commit_editmsg), NULL, env);
if (launch_editor(git_path(commit_editmsg), NULL, env)) {
fprintf(stderr,
"Please supply the message using either -m or -F option.\n");
exit(1);
}
}
if (!no_verify &&
@@ -877,7 +880,7 @@ static void print_summary(const char *prefix, const unsigned char *sha1)
}
}
int git_commit_config(const char *k, const char *v, void *cb)
static int git_commit_config(const char *k, const char *v, void *cb)
{
if (!strcmp(k, "commit.template"))
return git_config_string(&template_file, k, v);

View File

@@ -145,7 +145,7 @@ free_strings:
return ret;
}
char *normalize_value(const char *key, const char *value)
static char *normalize_value(const char *key, const char *value)
{
char *normalized;

View File

@@ -296,7 +296,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
* If the user asked for our exit code then don't start a
* pager or we would end up reporting its exit code instead.
*/
if (!DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS))
if (!DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS) &&
check_pager_config("diff") != 0)
setup_pager();
/*

View File

@@ -809,7 +809,7 @@ static struct ref_sort *default_sort(void)
return sort;
}
int opt_parse_sort(const struct option *opt, const char *arg, int unset)
static int opt_parse_sort(const struct option *opt, const char *arg, int unset)
{
struct ref_sort **sort_tail = opt->value;
struct ref_sort *s;

View File

@@ -377,6 +377,10 @@ static void fsck_dir(int i, char *path)
if (de->d_name[0] != '.')
break;
continue;
case 14:
if (prefixcmp(de->d_name, "tmp_obj_"))
break;
continue;
case 38:
sprintf(name, "%02x", i);
memcpy(name+2, de->d_name, len+1);

View File

@@ -431,7 +431,7 @@ static void merge_name(const char *remote, struct strbuf *msg)
sha1_to_hex(remote_head->sha1), remote);
}
int git_merge_config(const char *k, const char *v, void *cb)
static int git_merge_config(const char *k, const char *v, void *cb)
{
if (branch && !prefixcmp(k, "branch.") &&
!prefixcmp(k + 7, branch) &&

View File

@@ -13,6 +13,22 @@ static const char * const prune_usage[] = {
static int show_only;
static unsigned long expire;
static int prune_tmp_object(char *path, const char *filename)
{
const char *fullpath = mkpath("%s/%s", path, filename);
if (expire) {
struct stat st;
if (lstat(fullpath, &st))
return error("Could not stat '%s'", fullpath);
if (st.st_mtime > expire)
return 0;
}
printf("Removing stale temporary file %s\n", fullpath);
if (!show_only)
unlink(fullpath);
return 0;
}
static int prune_object(char *path, const char *filename, const unsigned char *sha1)
{
const char *fullpath = mkpath("%s/%s", path, filename);
@@ -53,6 +69,11 @@ static int prune_dir(int i, char *path)
if (de->d_name[0] != '.')
break;
continue;
case 14:
if (prefixcmp(de->d_name, "tmp_obj_"))
break;
prune_tmp_object(path, de->d_name);
continue;
case 38:
sprintf(name, "%02x", i);
memcpy(name+2, de->d_name, len+1);
@@ -105,23 +126,9 @@ static void remove_temporary_files(void)
dirname);
return;
}
while ((de = readdir(dir)) != NULL) {
if (!prefixcmp(de->d_name, "tmp_")) {
char name[PATH_MAX];
int c = snprintf(name, PATH_MAX, "%s/%s",
dirname, de->d_name);
if (c < 0 || c >= PATH_MAX)
continue;
if (expire) {
struct stat st;
if (stat(name, &st) != 0 || st.st_mtime >= expire)
continue;
}
printf("Removing stale temporary file %s\n", name);
if (!show_only)
unlink(name);
}
}
while ((de = readdir(dir)) != NULL)
if (!prefixcmp(de->d_name, "tmp_"))
prune_tmp_object(dirname, de->d_name);
closedir(dir);
}

View File

@@ -85,7 +85,7 @@ static void print_new_head_line(struct commit *commit)
printf("\n");
}
static int update_index_refresh(int fd, struct lock_file *index_lock)
static int update_index_refresh(int fd, struct lock_file *index_lock, int flags)
{
int result;
@@ -96,7 +96,8 @@ static int update_index_refresh(int fd, struct lock_file *index_lock)
if (read_cache() < 0)
return error("Could not read index");
result = refresh_cache(REFRESH_SAY_CHANGED) ? 1 : 0;
result = refresh_cache(flags) ? 1 : 0;
if (write_cache(fd, active_cache, active_nr) ||
commit_locked_index(index_lock))
return error ("Could not refresh index");
@@ -128,7 +129,7 @@ static void update_index_from_diff(struct diff_queue_struct *q,
}
static int read_from_tree(const char *prefix, const char **argv,
unsigned char *tree_sha1)
unsigned char *tree_sha1, int refresh_flags)
{
struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
int index_fd, index_was_discarded = 0;
@@ -152,7 +153,7 @@ static int read_from_tree(const char *prefix, const char **argv,
if (!index_was_discarded)
/* The index is still clobbered from do_diff_cache() */
discard_cache();
return update_index_refresh(index_fd, lock);
return update_index_refresh(index_fd, lock, refresh_flags);
}
static void prepend_reflog_action(const char *action, char *buf, size_t size)
@@ -246,7 +247,8 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
else if (reset_type != NONE)
die("Cannot do %s reset with paths.",
reset_type_names[reset_type]);
return read_from_tree(prefix, argv + i, sha1);
return read_from_tree(prefix, argv + i, sha1,
quiet ? REFRESH_QUIET : REFRESH_SAY_CHANGED);
}
if (reset_type == NONE)
reset_type = MIXED; /* by default */
@@ -286,7 +288,8 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
case SOFT: /* Nothing else to do. */
break;
case MIXED: /* Report what has not been updated. */
update_index_refresh(0, NULL);
update_index_refresh(0, NULL,
quiet ? REFRESH_QUIET : REFRESH_SAY_CHANGED);
break;
}

View File

@@ -23,59 +23,6 @@ static const char * const git_tag_usage[] = {
static char signingkey[1000];
void launch_editor(const char *path, struct strbuf *buffer, const char *const *env)
{
const char *editor, *terminal;
editor = getenv("GIT_EDITOR");
if (!editor && editor_program)
editor = editor_program;
if (!editor)
editor = getenv("VISUAL");
if (!editor)
editor = getenv("EDITOR");
terminal = getenv("TERM");
if (!editor && (!terminal || !strcmp(terminal, "dumb"))) {
fprintf(stderr,
"Terminal is dumb but no VISUAL nor EDITOR defined.\n"
"Please supply the message using either -m or -F option.\n");
exit(1);
}
if (!editor)
editor = "vi";
if (strcmp(editor, ":")) {
size_t len = strlen(editor);
int i = 0;
const char *args[6];
struct strbuf arg0;
strbuf_init(&arg0, 0);
if (strcspn(editor, "$ \t'") != len) {
/* there are specials */
strbuf_addf(&arg0, "%s \"$@\"", editor);
args[i++] = "sh";
args[i++] = "-c";
args[i++] = arg0.buf;
}
args[i++] = editor;
args[i++] = path;
args[i] = NULL;
if (run_command_v_opt_cd_env(args, 0, NULL, env))
die("There was a problem with the editor %s.", editor);
strbuf_release(&arg0);
}
if (!buffer)
return;
if (strbuf_read_file(buffer, path, 0) < 0)
die("could not read message file '%s': %s",
path, strerror(errno));
}
struct tag_filter {
const char *pattern;
int lines;
@@ -348,7 +295,11 @@ static void create_tag(const unsigned char *object, const char *tag,
write_or_die(fd, tag_template, strlen(tag_template));
close(fd);
launch_editor(path, buf, NULL);
if (launch_editor(path, buf, NULL)) {
fprintf(stderr,
"Please supply the message using either -m or -F option.\n");
exit(1);
}
unlink(path);
free(path);

View File

@@ -16,15 +16,13 @@ static const char deadchild[] =
static const char lostchild[] =
"git upload-archive: archiver process was lost";
#define MAX_ARGS (64)
static int run_upload_archive(int argc, const char **argv, const char *prefix)
{
const struct archiver *ar;
struct archiver_args args;
const char *sent_argv[MAX_ARGS];
const char *arg_cmd = "argument ";
char *p, buf[4096];
int treeish_idx;
int sent_argc;
int len;
@@ -48,7 +46,7 @@ static int run_upload_archive(int argc, const char **argv, const char *prefix)
if (len == 0)
break; /* got a flush */
if (sent_argc > MAX_ARGS - 2)
die("Too many options (>29)");
die("Too many options (>%d)", MAX_ARGS - 2);
if (p[len-1] == '\n') {
p[--len] = 0;
@@ -66,12 +64,7 @@ static int run_upload_archive(int argc, const char **argv, const char *prefix)
sent_argv[sent_argc] = NULL;
/* parse all options sent by the client */
treeish_idx = parse_archive_args(sent_argc, sent_argv, &ar, &args);
parse_treeish_arg(sent_argv + treeish_idx, &args, prefix);
parse_pathspec_arg(sent_argv + treeish_idx + 1, &args);
return ar->write_archive(&args);
return write_archive(sent_argc, sent_argv, prefix, 0);
}
static void error_clnt(const char *fmt, ...)

View File

@@ -18,6 +18,7 @@ extern int fmt_merge_msg(int merge_summary, struct strbuf *in,
struct strbuf *out);
extern int commit_tree(const char *msg, unsigned char *tree,
struct commit_list *parents, unsigned char *ret);
extern int check_pager_config(const char *cmd);
extern int cmd_add(int argc, const char **argv, const char *prefix);
extern int cmd_annotate(int argc, const char **argv, const char *prefix);

View File

@@ -436,8 +436,7 @@ void sort_in_topological_order(struct commit_list ** list, int lifo)
/* Mark them and clear the indegree */
for (next = orig; next; next = next->next) {
struct commit *commit = next->item;
commit->object.flags |= TOPOSORT;
commit->indegree = 0;
commit->indegree = 1;
}
/* update the indegree */
@@ -446,7 +445,7 @@ void sort_in_topological_order(struct commit_list ** list, int lifo)
while (parents) {
struct commit *parent = parents->item;
if (parent->object.flags & TOPOSORT)
if (parent->indegree)
parent->indegree++;
parents = parents->next;
}
@@ -464,7 +463,7 @@ void sort_in_topological_order(struct commit_list ** list, int lifo)
for (next = orig; next; next = next->next) {
struct commit *commit = next->item;
if (!commit->indegree)
if (commit->indegree == 1)
insert = &commit_list_insert(commit, insert)->next;
}
@@ -486,7 +485,7 @@ void sort_in_topological_order(struct commit_list ** list, int lifo)
for (parents = commit->parents; parents ; parents = parents->next) {
struct commit *parent=parents->item;
if (!(parent->object.flags & TOPOSORT))
if (!parent->indegree)
continue;
/*
@@ -494,7 +493,7 @@ void sort_in_topological_order(struct commit_list ** list, int lifo)
* when all their children have been emitted thereby
* guaranteeing topological order.
*/
if (!--parent->indegree) {
if (--parent->indegree == 1) {
if (!lifo)
insert_by_date(parent, &work);
else
@@ -505,7 +504,7 @@ void sort_in_topological_order(struct commit_list ** list, int lifo)
* work_item is a commit all of whose children
* have already been emitted. we can emit it now.
*/
commit->object.flags &= ~TOPOSORT;
commit->indegree = 0;
*pptr = work_item;
pptr = &work_item->next;
}

View File

@@ -223,3 +223,15 @@ void mingw_open_html(const char *path);
char **copy_environ(void);
void free_environ(char **env);
char **env_setenv(char **env, const char *name);
/*
* A replacement of main() that ensures that argv[0] has a path
*/
#define main(c,v) main(int argc, const char **argv) \
{ \
static int mingw_main(); \
argv[0] = xstrdup(_pgmptr); \
return mingw_main(argc, argv); \
} \
static int mingw_main(c,v)

View File

@@ -489,7 +489,7 @@ _git_am ()
{
local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
if [ -d "$dir"/rebase-apply ]; then
__gitcomp "--skip --resolved"
__gitcomp "--skip --resolved --abort"
return
fi
case "$cur" in
@@ -626,6 +626,8 @@ _git_bundle ()
_git_checkout ()
{
__git_has_doubledash && return
__gitcomp "$(__git_refs)"
}
@@ -1170,6 +1172,20 @@ _git_reset ()
__gitcomp "$(__git_refs)"
}
_git_rm ()
{
__git_has_doubledash && return
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
--*)
__gitcomp "--cached --dry-run --ignore-unmatch --quiet"
return
;;
esac
COMPREPLY=()
}
_git_shortlog ()
{
__git_has_doubledash && return
@@ -1210,6 +1226,22 @@ _git_show ()
__git_complete_file
}
_git_show_branch ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
--*)
__gitcomp "
--all --remotes --topo-order --current --more=
--list --independent --merge-base --no-name
--sha1-name --topics --reflog
"
return
;;
esac
__git_complete_revlist
}
_git_stash ()
{
local subcommands='save list show apply clear drop pop create'
@@ -1425,10 +1457,11 @@ _git ()
rebase) _git_rebase ;;
remote) _git_remote ;;
reset) _git_reset ;;
rm) _git_rm ;;
send-email) _git_send_email ;;
shortlog) _git_shortlog ;;
show) _git_show ;;
show-branch) _git_log ;;
show-branch) _git_show_branch ;;
stash) _git_stash ;;
submodule) _git_submodule ;;
svn) _git_svn ;;

View File

@@ -933,7 +933,7 @@ while ($to_rev < $opt_l) {
$to_rev = $from_rev + $repack_after;
$to_rev = $opt_l if $opt_l < $to_rev;
print "Fetching from $from_rev to $to_rev ...\n" if $opt_v;
$svn->{'svn'}->get_log("/",$from_rev,$to_rev,0,1,1,\&commit_all);
$svn->{'svn'}->get_log("",$from_rev,$to_rev,0,1,1,\&commit_all);
my $pid = fork();
die "Fork: $!\n" unless defined $pid;
unless($pid) {

View File

@@ -906,7 +906,7 @@ class P4Sync(Command):
if stat['type'] in ('text+ko', 'unicode+ko', 'binary+ko'):
text = re.sub(r'(?i)\$(Id|Header):[^$]*\$',r'$\1$', text)
elif stat['type'] in ('text+k', 'ktext', 'kxtext', 'unicode+k', 'binary+k'):
text = re.sub(r'(?i)\$(Id|Header|Author|Date|DateTime|Change|File|Revision):[^$]*\$',r'$\1$', text)
text = re.sub(r'\$(Id|Header|Author|Date|DateTime|Change|File|Revision):[^$]*\$',r'$\1$', text)
contents[stat['depotFile']] = text

View File

@@ -16,6 +16,7 @@
static int log_syslog;
static int verbose;
static int reuseaddr;
static int child_handler_pipe[2];
static const char daemon_usage[] =
"git daemon [--verbose] [--syslog] [--export-all]\n"
@@ -788,6 +789,7 @@ static void child_handler(int signo)
pid = -pid;
dead_child[reaped % MAX_CHILDREN] = pid;
children_reaped = reaped + 1;
write(child_handler_pipe[1], &status, 1);
continue;
}
break;
@@ -933,29 +935,24 @@ static int service_loop(int socknum, int *socklist)
struct pollfd *pfd;
int i;
pfd = xcalloc(socknum, sizeof(struct pollfd));
if (pipe(child_handler_pipe) < 0)
die ("Could not set up pipe for child handler");
pfd = xcalloc(socknum + 1, sizeof(struct pollfd));
for (i = 0; i < socknum; i++) {
pfd[i].fd = socklist[i];
pfd[i].events = POLLIN;
}
pfd[socknum].fd = child_handler_pipe[0];
pfd[socknum].events = POLLIN;
signal(SIGCHLD, child_handler);
for (;;) {
int i;
int timeout;
/*
* This 1-sec timeout could lead to idly looping but it is
* here so that children culled in child_handler() are reported
* without too much delay. We could probably set up a pipe
* to ourselves that we poll, and write to the fd from child_handler()
* to wake us up (and consume it when the poll() returns...
*/
timeout = (children_spawned != children_deleted) ? 1000 : -1;
i = poll(pfd, socknum, timeout);
if (i < 0) {
if (poll(pfd, socknum + 1, -1) < 0) {
if (errno != EINTR) {
error("poll failed, resuming: %s",
strerror(errno));
@@ -963,9 +960,9 @@ static int service_loop(int socknum, int *socklist)
}
continue;
}
if (i == 0) {
if (pfd[socknum].revents & POLLIN) {
read(child_handler_pipe[0], &i, 1);
check_dead_children();
continue;
}
for (i = 0; i < socknum; i++) {

56
editor.c Normal file
View File

@@ -0,0 +1,56 @@
#include "cache.h"
#include "strbuf.h"
#include "run-command.h"
int launch_editor(const char *path, struct strbuf *buffer, const char *const *env)
{
const char *editor, *terminal;
editor = getenv("GIT_EDITOR");
if (!editor && editor_program)
editor = editor_program;
if (!editor)
editor = getenv("VISUAL");
if (!editor)
editor = getenv("EDITOR");
terminal = getenv("TERM");
if (!editor && (!terminal || !strcmp(terminal, "dumb")))
return error("Terminal is dumb but no VISUAL nor EDITOR defined.");
if (!editor)
editor = "vi";
if (strcmp(editor, ":")) {
size_t len = strlen(editor);
int i = 0;
int failed;
const char *args[6];
struct strbuf arg0;
strbuf_init(&arg0, 0);
if (strcspn(editor, "$ \t'") != len) {
/* there are specials */
strbuf_addf(&arg0, "%s \"$@\"", editor);
args[i++] = "sh";
args[i++] = "-c";
args[i++] = arg0.buf;
}
args[i++] = editor;
args[i++] = path;
args[i] = NULL;
failed = run_command_v_opt_cd_env(args, 0, NULL, env);
strbuf_release(&arg0);
if (failed)
return error("There was a problem with the editor '%s'.",
editor);
}
if (!buffer)
return 0;
if (strbuf_read_file(buffer, path, 0) < 0)
return error("could not read file '%s': %s",
path, strerror(errno));
return 0;
}

View File

@@ -5,51 +5,23 @@
extern char **environ;
static const char *argv_exec_path;
static const char *builtin_exec_path(void)
{
#ifndef __MINGW32__
return GIT_EXEC_PATH;
#else
int len;
char *p, *q, *sl;
static char *ep;
if (ep)
return ep;
len = strlen(_pgmptr);
if (len < 2)
return ep = ".";
p = ep = xmalloc(len+1);
q = _pgmptr;
sl = NULL;
/* copy program name, turn '\\' into '/', skip last part */
while ((*p = *q)) {
if (*q == '\\' || *q == '/') {
*p = '/';
sl = p;
}
p++, q++;
}
if (sl)
*sl = '\0';
else
ep[0] = '.', ep[1] = '\0';
return ep;
#endif
}
static const char *argv0_path;
const char *system_path(const char *path)
{
if (!is_absolute_path(path)) {
if (!is_absolute_path(path) && argv0_path) {
struct strbuf d = STRBUF_INIT;
strbuf_addf(&d, "%s/%s", git_exec_path(), path);
strbuf_addf(&d, "%s/%s", argv0_path, path);
path = strbuf_detach(&d, NULL);
}
return path;
}
void git_set_argv0_path(const char *path)
{
argv0_path = path;
}
void git_set_argv_exec_path(const char *exec_path)
{
argv_exec_path = exec_path;
@@ -69,7 +41,7 @@ const char *git_exec_path(void)
return env;
}
return builtin_exec_path();
return system_path(GIT_EXEC_PATH);
}
static void add_path(struct strbuf *out, const char *path)
@@ -78,13 +50,13 @@ static void add_path(struct strbuf *out, const char *path)
if (is_absolute_path(path))
strbuf_addstr(out, path);
else
strbuf_addstr(out, make_absolute_path(path));
strbuf_addstr(out, make_nonrelative_path(path));
strbuf_addch(out, PATH_SEP);
}
}
void setup_path(const char *cmd_path)
void setup_path(void)
{
const char *old_path = getenv("PATH");
struct strbuf new_path;
@@ -93,8 +65,8 @@ void setup_path(const char *cmd_path)
add_path(&new_path, argv_exec_path);
add_path(&new_path, getenv(EXEC_PATH_ENVIRONMENT));
add_path(&new_path, builtin_exec_path());
add_path(&new_path, cmd_path);
add_path(&new_path, system_path(GIT_EXEC_PATH));
add_path(&new_path, argv0_path);
if (old_path)
strbuf_addstr(&new_path, old_path);

View File

@@ -2,8 +2,9 @@
#define GIT_EXEC_CMD_H
extern void git_set_argv_exec_path(const char *exec_path);
extern void git_set_argv0_path(const char *path);
extern const char* git_exec_path(void);
extern void setup_path(const char *);
extern void setup_path(void);
extern int execv_git_cmd(const char **argv); /* NULL terminated */
extern int execl_git_cmd(const char *cmd, ...);
extern const char *system_path(const char *path);

View File

@@ -6,8 +6,7 @@ SUBDIRECTORY_OK=Yes
OPTIONS_KEEPDASHDASH=
OPTIONS_SPEC="\
git am [options] [<mbox>|<Maildir>...]
git am [options] --resolved
git am [options] --skip
git am [options] (--resolved | --skip | --abort)
--
d,dotest= (removed -- do not use)
i,interactive run interactively
@@ -456,7 +455,7 @@ do
stop_here $this
fi
printf 'Applying %s\n' "$FIRSTLINE"
printf 'Applying: %s\n' "$FIRSTLINE"
case "$resolved" in
'')

View File

@@ -97,9 +97,11 @@ USAGE="[--env-filter <command>] [--tree-filter <command>] \
OPTIONS_SPEC=
. git-sh-setup
git diff-files --quiet &&
if [ "$(is_bare_repository)" = false ]; then
git diff-files --quiet &&
git diff-index --cached --quiet HEAD -- ||
die "Cannot rewrite branch(es) with a dirty working directory."
fi
tempdir=.git-rewrite
filter_env=
@@ -434,18 +436,20 @@ rm -rf "$tempdir"
trap - 0
unset GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE
test -z "$ORIG_GIT_DIR" || {
GIT_DIR="$ORIG_GIT_DIR" && export GIT_DIR
}
test -z "$ORIG_GIT_WORK_TREE" || {
GIT_WORK_TREE="$ORIG_GIT_WORK_TREE" &&
export GIT_WORK_TREE
}
test -z "$ORIG_GIT_INDEX_FILE" || {
GIT_INDEX_FILE="$ORIG_GIT_INDEX_FILE" &&
export GIT_INDEX_FILE
}
git read-tree -u -m HEAD
if [ "$(is_bare_repository)" = false ]; then
unset GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE
test -z "$ORIG_GIT_DIR" || {
GIT_DIR="$ORIG_GIT_DIR" && export GIT_DIR
}
test -z "$ORIG_GIT_WORK_TREE" || {
GIT_WORK_TREE="$ORIG_GIT_WORK_TREE" &&
export GIT_WORK_TREE
}
test -z "$ORIG_GIT_INDEX_FILE" || {
GIT_INDEX_FILE="$ORIG_GIT_INDEX_FILE" &&
export GIT_INDEX_FILE
}
git read-tree -u -m HEAD
fi
exit $ret

View File

@@ -107,9 +107,9 @@ error_on_no_merge_candidates () {
}
test true = "$rebase" && {
git update-index --refresh &&
git diff-files --quiet &&
git diff-index --cached --quiet HEAD -- ||
git update-index --ignore-submodules --refresh &&
git diff-files --ignore-submodules --quiet &&
git diff-index --ignore-submodules --cached --quiet HEAD -- ||
die "refusing to pull with rebase: your working tree is not up-to-date"
. git-parse-remote &&

View File

@@ -277,7 +277,7 @@ do_next () {
die_with_patch $sha1 "Could not apply $sha1... $rest"
make_patch $sha1
: > "$DOTEST"/amend
warn
warn "Stopped at $sha1... $rest"
warn "You can amend the commit now, with"
warn
warn " git commit --amend"

View File

@@ -882,7 +882,7 @@ foreach my $t (@files) {
}
elsif (/^Content-type:/i) {
$has_content_type = 1;
if (/charset="?[^ "]+/) {
if (/charset="?([^ "]+)/) {
$body_encoding = $1;
}
push @xh, $_;

View File

@@ -93,7 +93,7 @@ save_stash () {
shift
esac
stash_msg="$1"
stash_msg="$*"
if no_changes
then
@@ -267,7 +267,7 @@ show)
;;
save)
shift
save_stash "$*"
save_stash "$@"
;;
apply)
shift

View File

@@ -3340,6 +3340,7 @@ sub new {
$self->{rm} = { };
$self->{path_prefix} = length $self->{svn_path} ?
"$self->{svn_path}/" : '';
$self->{config} = $opts->{config};
return $self;
}
@@ -3528,6 +3529,57 @@ sub ensure_path {
return $bat->{$c};
}
# Subroutine to convert a globbing pattern to a regular expression.
# From perl cookbook.
sub glob2pat {
my $globstr = shift;
my %patmap = ('*' => '.*', '?' => '.', '[' => '[', ']' => ']');
$globstr =~ s{(.)} { $patmap{$1} || "\Q$1" }ge;
return '^' . $globstr . '$';
}
sub check_autoprop {
my ($self, $pattern, $properties, $file, $fbat) = @_;
# Convert the globbing pattern to a regular expression.
my $regex = glob2pat($pattern);
# Check if the pattern matches the file name.
if($file =~ m/($regex)/) {
# Parse the list of properties to set.
my @props = split(/;/, $properties);
foreach my $prop (@props) {
# Parse 'name=value' syntax and set the property.
if ($prop =~ /([^=]+)=(.*)/) {
my ($n,$v) = ($1,$2);
for ($n, $v) {
s/^\s+//; s/\s+$//;
}
$self->change_file_prop($fbat, $n, $v);
}
}
}
}
sub apply_autoprops {
my ($self, $file, $fbat) = @_;
my $conf_t = ${$self->{config}}{'config'};
no warnings 'once';
# Check [miscellany]/enable-auto-props in svn configuration.
if (SVN::_Core::svn_config_get_bool(
$conf_t,
$SVN::_Core::SVN_CONFIG_SECTION_MISCELLANY,
$SVN::_Core::SVN_CONFIG_OPTION_ENABLE_AUTO_PROPS,
0)) {
# Auto-props are enabled. Enumerate them to look for matches.
my $callback = sub {
$self->check_autoprop($_[0], $_[1], $file, $fbat);
};
SVN::_Core::svn_config_enumerate(
$conf_t,
$SVN::_Core::SVN_CONFIG_SECTION_AUTO_PROPS,
$callback);
}
}
sub A {
my ($self, $m) = @_;
my ($dir, $file) = split_path($m->{file_b});
@@ -3535,6 +3587,7 @@ sub A {
my $fbat = $self->add_file($self->repo_path($m->{file_b}), $pbat,
undef, -1);
print "\tA\t$m->{file_b}\n" unless $::_q;
$self->apply_autoprops($file, $fbat);
$self->chg_file($fbat, $m);
$self->close_file($fbat,undef,$self->{pool});
}

5
git.c
View File

@@ -418,7 +418,6 @@ int main(int argc, const char **argv)
{
const char *cmd = argv[0] && *argv[0] ? argv[0] : "git-help";
char *slash = (char *)cmd + strlen(cmd);
const char *cmd_path = NULL;
int done_alias = 0;
/*
@@ -431,7 +430,7 @@ int main(int argc, const char **argv)
while (cmd <= slash && !is_dir_sep(*slash));
if (cmd <= slash) {
*slash++ = 0;
cmd_path = cmd;
git_set_argv0_path(cmd);
cmd = slash;
}
@@ -475,7 +474,7 @@ int main(int argc, const char **argv)
* environment, and the $(gitexecdir) from the Makefile at build
* time.
*/
setup_path(cmd_path);
setup_path();
while (1) {
/* See if it's an internal command */

View File

@@ -699,6 +699,10 @@ static struct object_entry *append_obj_to_pack(
write_or_die(output_fd, header, n);
obj[0].idx.crc32 = crc32(0, Z_NULL, 0);
obj[0].idx.crc32 = crc32(obj[0].idx.crc32, header, n);
obj[0].size = size;
obj[0].hdr_size = n;
obj[0].type = type;
obj[0].real_type = type;
obj[1].idx.offset = obj[0].idx.offset + n;
obj[1].idx.offset += write_compressed(output_fd, buf, size, &obj[0].idx.crc32);
hashcpy(obj->idx.sha1, sha1);

36
path.c
View File

@@ -291,42 +291,6 @@ int adjust_shared_perm(const char *path)
return 0;
}
static const char *get_pwd_cwd(void)
{
static char cwd[PATH_MAX + 1];
char *pwd;
struct stat cwd_stat, pwd_stat;
if (getcwd(cwd, PATH_MAX) == NULL)
return NULL;
pwd = getenv("PWD");
if (pwd && strcmp(pwd, cwd)) {
stat(cwd, &cwd_stat);
if (!stat(pwd, &pwd_stat) &&
pwd_stat.st_dev == cwd_stat.st_dev &&
pwd_stat.st_ino == cwd_stat.st_ino) {
strlcpy(cwd, pwd, PATH_MAX);
}
}
return cwd;
}
const char *make_nonrelative_path(const char *path)
{
static char buf[PATH_MAX + 1];
if (is_absolute_path(path)) {
if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX)
die ("Too long path: %.*s", 60, path);
} else {
const char *cwd = get_pwd_cwd();
if (!cwd)
die("Cannot determine the current working directory");
if (snprintf(buf, PATH_MAX, "%s/%s", cwd, path) >= PATH_MAX)
die ("Too long path: %.*s", 60, path);
}
return buf;
}
const char *make_relative_path(const char *abs, const char *base)
{
static char buf[PATH_MAX + 1];

View File

@@ -26,13 +26,18 @@ ifdef NO_PERL_MAKEMAKER
# $(instdir_SQ) and split it at colons.
instdir_SQ = $(subst ','\'',$(shell cmd /x/d/c "set TEMP=$(prefix)/lib && sh -c 'echo \$$TEMP'"))
$(makfile): ../GIT-CFLAGS Makefile
echo all: > $@
echo ' :' >> $@
echo all: private-Error.pm Git.pm > $@
echo ' mkdir -p blib/lib' >> $@
echo ' $(RM) blib/lib/Git.pm; cp Git.pm blib/lib/' >> $@
echo ' $(RM) blib/lib/Error.pm' >> $@
'$(PERL_PATH_SQ)' -MError -e 'exit($$Error::VERSION < 0.15009)' || \
echo ' cp private-Error.pm blib/lib/Error.pm' >> $@
echo install: >> $@
echo ' mkdir -p $(instdir_SQ)' >> $@
echo ' $(RM) $(instdir_SQ)/Git.pm; cp Git.pm $(instdir_SQ)' >> $@
echo ' $(RM) $(instdir_SQ)/Error.pm; \
cp private-Error.pm $(instdir_SQ)/Error.pm' >> $@
echo ' $(RM) $(instdir_SQ)/Error.pm' >> $@
'$(PERL_PATH_SQ)' -MError -e 'exit($$Error::VERSION < 0.15009)' || \
echo ' cp private-Error.pm $(instdir_SQ)/Error.pm' >> $@
echo instlibdir: >> $@
echo ' echo $(instdir_SQ)' >> $@
else

View File

@@ -482,7 +482,7 @@ int main(int argc, char **argv)
if (!dir)
usage(receive_pack_usage);
setup_path(NULL);
setup_path();
if (!enter_repo(dir, 0))
die("'%s': unable to chdir or not a git archive", dir);

View File

@@ -12,8 +12,7 @@
#define CHILD_SHOWN (1u<<6)
#define ADDED (1u<<7) /* Parents already parsed and added? */
#define SYMMETRIC_LEFT (1u<<8)
#define TOPOSORT (1u<<9) /* In the active toposort list.. */
#define ALL_REV_FLAGS ((1u<<10)-1)
#define ALL_REV_FLAGS ((1u<<9)-1)
struct rev_info;
struct log_info;

View File

@@ -273,7 +273,7 @@ int dwim_log(const char *str, int len, unsigned char *sha1, char **log)
const char *ref, *it;
strcpy(path, mkpath(*p, len, str));
ref = resolve_ref(path, hash, 0, NULL);
ref = resolve_ref(path, hash, 1, NULL);
if (!ref)
continue;
if (!stat(git_path("logs/%s", path), &st) &&

View File

@@ -15,7 +15,7 @@ static int do_generic_cmd(const char *me, char *arg)
{
const char *my_argv[4];
setup_path(NULL);
setup_path();
if (!arg || !(arg = sq_dequote(arg)))
die("bad argument");
if (prefixcmp(me, "git-"))
@@ -37,7 +37,7 @@ static int do_cvs_cmd(const char *me, char *arg)
if (!arg || strcmp(arg, "server"))
die("git-cvsserver only handles server: %s", arg);
setup_path(NULL);
setup_path();
return execv_git_cmd(cvsserver_argv);
}

View File

@@ -123,6 +123,6 @@ extern int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint);
extern int strbuf_getline(struct strbuf *, FILE *, int);
extern void stripspace(struct strbuf *buf, int skip_comments);
extern void launch_editor(const char *path, struct strbuf *buffer, const char *const *env);
extern int launch_editor(const char *path, struct strbuf *buffer, const char *const *env);
#endif /* STRBUF_H */

View File

@@ -66,7 +66,7 @@ test_expect_success 'check hash-object' '
test_expect_success 'check cat-file' '
git cat-file blob $SHA >actual &&
diff -u bar actual
test_cmp bar actual
'
test_expect_success 'check update-index' '

View File

@@ -118,7 +118,7 @@ test_expect_success \
git update-index --add frotz &&
git read-tree -m -u $treeH $treeM &&
git ls-files --stage >6.out &&
diff -U0 M.out 6.out &&
test_cmp M.out 6.out &&
check_cache_at frotz clean &&
sum bozbar frotz nitfol >actual3.sum &&
cmp M.sum actual3.sum &&
@@ -135,7 +135,7 @@ test_expect_success \
echo frotz frotz >frotz &&
git read-tree -m -u $treeH $treeM &&
git ls-files --stage >7.out &&
diff -U0 M.out 7.out &&
test_cmp M.out 7.out &&
check_cache_at frotz dirty &&
sum bozbar frotz nitfol >actual7.sum &&
if cmp M.sum actual7.sum; then false; else :; fi &&
@@ -270,7 +270,7 @@ test_expect_success \
git update-index --add bozbar &&
git read-tree -m -u $treeH $treeM &&
git ls-files --stage >18.out &&
diff -U0 M.out 18.out &&
test_cmp M.out 18.out &&
check_cache_at bozbar clean &&
sum bozbar frotz nitfol >actual18.sum &&
cmp M.sum actual18.sum'
@@ -284,7 +284,7 @@ test_expect_success \
echo gnusto gnusto >bozbar &&
git read-tree -m -u $treeH $treeM &&
git ls-files --stage >19.out &&
diff -U0 M.out 19.out &&
test_cmp M.out 19.out &&
check_cache_at bozbar dirty &&
sum frotz nitfol >actual19.sum &&
grep -v bozbar M.sum > expected19.sum &&
@@ -303,7 +303,7 @@ test_expect_success \
git update-index --add bozbar &&
git read-tree -m -u $treeH $treeM &&
git ls-files --stage >20.out &&
diff -U0 M.out 20.out &&
test_cmp M.out 20.out &&
check_cache_at bozbar clean &&
sum bozbar frotz nitfol >actual20.sum &&
cmp M.sum actual20.sum'
@@ -344,7 +344,7 @@ test_expect_success \
git update-index --add DF &&
git read-tree -m -u $treeDF $treeDFDF &&
git ls-files --stage >DFDFcheck.out &&
diff -U0 DFDF.out DFDFcheck.out &&
test_cmp DFDF.out DFDFcheck.out &&
check_cache_at DF/DF clean'
test_done

50
t/t2010-checkout-ambiguous.sh Executable file
View File

@@ -0,0 +1,50 @@
#!/bin/sh
test_description='checkout and pathspecs/refspecs ambiguities'
. ./test-lib.sh
test_expect_success 'setup' '
echo hello >world &&
echo hello >all &&
git add all world &&
git commit -m initial &&
git branch world
'
test_expect_success 'reference must be a tree' '
test_must_fail git checkout $(git hash-object ./all) --
'
test_expect_success 'branch switching' '
test "refs/heads/master" = "$(git symbolic-ref HEAD)" &&
git checkout world -- &&
test "refs/heads/world" = "$(git symbolic-ref HEAD)"
'
test_expect_success 'checkout world from the index' '
echo bye > world &&
git checkout -- world &&
git diff --exit-code --quiet
'
test_expect_success 'non ambiguous call' '
git checkout all
'
test_expect_success 'allow the most common case' '
git checkout world &&
test "refs/heads/world" = "$(git symbolic-ref HEAD)"
'
test_expect_success 'check ambiguity' '
test_must_fail git checkout world all
'
test_expect_success 'disambiguate checking out from a tree-ish' '
echo bye > world &&
git checkout world -- world &&
git diff --exit-code --quiet
'
test_done

View File

@@ -115,12 +115,12 @@ test_expect_success modify '
test_expect_success diff-files '
git diff-files --raw >actual &&
diff -u expect-files actual
test_cmp expect-files actual
'
test_expect_success diff-index '
git diff-index --raw HEAD -- >actual &&
diff -u expect-index actual
test_cmp expect-index actual
'
test_expect_success 'add -u' '
@@ -128,7 +128,7 @@ test_expect_success 'add -u' '
cp -p ".git/index" ".git/saved-index" &&
git add -u &&
git ls-files -s >actual &&
diff -u expect-final actual
test_cmp expect-final actual
'
test_expect_success 'commit -a' '
@@ -139,11 +139,11 @@ test_expect_success 'commit -a' '
fi &&
git commit -m "second" -a &&
git ls-files -s >actual &&
diff -u expect-final actual &&
test_cmp expect-final actual &&
rm -f .git/index &&
git read-tree HEAD &&
git ls-files -s >actual &&
diff -u expect-final actual
test_cmp expect-final actual
'
test_done

View File

@@ -202,7 +202,7 @@ test_expect_success \
test_expect_success \
'branch from non-branch HEAD w/--track causes failure' \
'!(git branch --track my10 HEAD^)'
'test_must_fail git branch --track my10 HEAD^'
# Keep this test last, as it changes the current branch
cat >expect <<EOF

59
t/t3202-show-branch-octopus.sh Executable file
View File

@@ -0,0 +1,59 @@
#!/bin/sh
test_description='test show-branch with more than 8 heads'
. ./test-lib.sh
numbers="1 2 3 4 5 6 7 8 9 10"
test_expect_success 'setup' '
> file &&
git add file &&
test_tick &&
git commit -m initial &&
for i in $numbers
do
git checkout -b branch$i master &&
> file$i &&
git add file$i &&
test_tick &&
git commit -m branch$i || break
done
'
cat > expect << EOF
! [branch1] branch1
! [branch2] branch2
! [branch3] branch3
! [branch4] branch4
! [branch5] branch5
! [branch6] branch6
! [branch7] branch7
! [branch8] branch8
! [branch9] branch9
* [branch10] branch10
----------
* [branch10] branch10
+ [branch9] branch9
+ [branch8] branch8
+ [branch7] branch7
+ [branch6] branch6
+ [branch5] branch5
+ [branch4] branch4
+ [branch3] branch3
+ [branch2] branch2
+ [branch1] branch1
+++++++++* [branch10^] initial
EOF
test_expect_success 'show-branch with more than 8 branches' '
git show-branch $(for i in $numbers; do echo branch$i; done) > out &&
test_cmp expect out
'
test_done

View File

@@ -49,12 +49,12 @@ test_expect_success 'apply in reverse' '
test_expect_success 'setup separate repository lacking postimage' '
git tar-tree initial initial | tar xf - &&
git tar-tree initial initial | $TAR xf - &&
(
cd initial && git init && git add .
) &&
git tar-tree second second | tar xf - &&
git tar-tree second second | $TAR xf - &&
(
cd second && git init && git add .
)

View File

@@ -17,6 +17,8 @@ test_expect_success setup '
for i in 2 3 4 5 6
do
echo $i >>file-1 &&
echo $i >otherfile-$i &&
git add otherfile-$i &&
test_tick &&
git commit -a -m $i || break
done &&
@@ -43,7 +45,7 @@ do
test_expect_success "am$with3 --skip continue after failed am$with3" '
test_must_fail git-am$with3 --skip >output &&
test "$(grep "^Applying" output)" = "Applying 6" &&
test "$(grep "^Applying" output)" = "Applying: 6" &&
test_cmp file-2-expect file-2 &&
test ! -f .git/rr-cache/MERGE_RR
'

View File

@@ -71,4 +71,5 @@ test_expect_success 'diff-filter=D' '
test_done
test_done

View File

@@ -25,7 +25,6 @@ commit id embedding:
'
. ./test-lib.sh
TAR=${TAR:-tar}
UNZIP=${UNZIP:-unzip}
test "$no_symlinks" && {
@@ -84,7 +83,7 @@ test_expect_success \
test_expect_success \
'validate file modification time' \
'mkdir extract &&
$TAR xf b.tar -C extract a/a &&
"$TAR" xf b.tar -C extract a/a &&
perl -e '\''print((stat("extract/a/a"))[9], "\n")'\'' >b.mtime &&
echo "1117231200" >expected.mtime &&
diff expected.mtime b.mtime'
@@ -96,7 +95,7 @@ test_expect_success \
test_expect_success \
'extract tar archive' \
'(cd b && $TAR xf -) <b.tar'
'(cd b && "$TAR" xf -) <b.tar'
test_expect_success \
'validate filenames' \
@@ -113,7 +112,7 @@ test_expect_success \
test_expect_success \
'extract tar archive with prefix' \
'(cd c && $TAR xf -) <c.tar'
'(cd c && "$TAR" xf -) <c.tar'
test_expect_success \
'validate filenames with prefix' \
@@ -133,7 +132,7 @@ test_expect_success \
test_expect_success \
'extract substfiles' \
'(mkdir f && cd f && $TAR xf -) <f.tar'
'(mkdir f && cd f && "$TAR" xf -) <f.tar'
test_expect_success \
'validate substfile contents' \
@@ -145,7 +144,7 @@ test_expect_success \
test_expect_success \
'extract substfiles from archive with prefix' \
'(mkdir g && cd g && $TAR xf -) <g.tar'
'(mkdir g && cd g && "$TAR" xf -) <g.tar'
test_expect_success \
'validate substfile contents from archive with prefix' \

26
t/t5602-clone-remote-exec.sh Executable file
View File

@@ -0,0 +1,26 @@
#!/bin/sh
test_description=clone
. ./test-lib.sh
test_expect_success setup '
echo "#!/bin/sh" > not_ssh
echo "echo \"\$*\" > not_ssh_output" >> not_ssh
echo "exit 1" >> not_ssh
chmod +x not_ssh
'
test_expect_success 'clone calls git-upload-pack unqualified with no -u option' '
GIT_SSH=./not_ssh git clone localhost:/path/to/repo junk
echo "localhost git-upload-pack '\''/path/to/repo'\''" >expected
test_cmp expected not_ssh_output
'
test_expect_success 'clone calls specified git-upload-pack with -u option' '
GIT_SSH=./not_ssh git clone -u /something/bin/git-upload-pack localhost:/path/to/repo junk
echo "localhost /something/bin/git-upload-pack '\''/path/to/repo'\''" >expected
test_cmp expected not_ssh_output
'
test_done

View File

@@ -38,6 +38,14 @@ test_expect_success 'result is really identical' '
test $H = $(git rev-parse HEAD)
'
test_expect_success 'rewrite bare repository identically' '
(git config core.bare true && cd .git && git-filter-branch branch)
'
git config core.bare false
test_expect_success 'result is really identical' '
test $H = $(git rev-parse HEAD)
'
test_expect_success 'rewrite, renaming a specific file' '
git-filter-branch -f --tree-filter "mv d doh || :" HEAD
'

View File

@@ -339,6 +339,6 @@ test_expect_success \
git checkout -b delete-me master &&
rm .git/refs/heads/delete-me &&
test refs/heads/delete-me = "$(git symbolic-ref HEAD)" &&
!(git checkout --track -b track)'
test_must_fail git checkout --track -b track'
test_done

View File

@@ -228,10 +228,12 @@ EOF
test_expect_success 'a SIGTERM should break locks' '
echo >>negative &&
"$SHELL_PATH" -c '\''
! "$SHELL_PATH" -c '\''
echo kill -TERM $$ >> .git/FAKE_EDITOR
GIT_EDITOR=.git/FAKE_EDITOR exec git commit -a'\'' && exit 1 # should fail
! test -f .git/index.lock
GIT_EDITOR=.git/FAKE_EDITOR
export GIT_EDITOR
exec git commit -a'\'' &&
test ! -f .git/index.lock
'
rm -f .git/MERGE_MSG .git/COMMIT_EDITMSG

View File

@@ -112,6 +112,21 @@ test_expect_success 'setup conflicted merge' '
# recusive is choosen.
test_expect_success 'merge picks up the best result' '
git config --unset-all pull.twohead &&
git reset --hard c5 &&
git merge -s resolve c6
resolve_count=$(conflict_count) &&
git reset --hard c5 &&
git merge -s recursive c6
recursive_count=$(conflict_count) &&
git reset --hard c5 &&
git merge -s recursive -s resolve c6
auto_count=$(conflict_count) &&
test $auto_count = $recursive_count &&
test $auto_count != $resolve_count
'
test_expect_success 'merge picks up the best result (from config)' '
git config pull.twohead "recursive resolve" &&
git reset --hard c5 &&
git merge -s resolve c6

View File

@@ -0,0 +1,86 @@
#!/bin/sh
#
# Copyright (c) 2008 Brad King
test_description='git-svn dcommit honors auto-props'
. ./lib-git-svn.sh
generate_auto_props() {
cat << EOF
[miscellany]
enable-auto-props=$1
[auto-props]
*.sh = svn:mime-type=application/x-shellscript; svn:eol-style=LF
*.txt = svn:mime-type=text/plain; svn:eol-style = native
EOF
}
test_expect_success 'initialize git-svn' '
mkdir import &&
(
cd import &&
echo foo >foo &&
svn import -m "import for git-svn" . "$svnrepo"
) &&
rm -rf import &&
git-svn init "$svnrepo"
git-svn fetch
'
test_expect_success 'enable auto-props config' '
cd "$gittestrepo" &&
mkdir user &&
generate_auto_props yes >user/config
'
test_expect_success 'add files matching auto-props' '
cd "$gittestrepo" &&
echo "#!$SHELL_PATH" >exec1.sh &&
chmod +x exec1.sh &&
echo "hello" >hello.txt &&
echo bar >bar &&
git add exec1.sh hello.txt bar &&
git commit -m "files for enabled auto-props" &&
git svn dcommit --config-dir=user
'
test_expect_success 'disable auto-props config' '
cd "$gittestrepo" &&
generate_auto_props no >user/config
'
test_expect_success 'add files matching disabled auto-props' '
cd "$gittestrepo" &&
echo "#$SHELL_PATH" >exec2.sh &&
chmod +x exec2.sh &&
echo "world" >world.txt &&
echo zot >zot &&
git add exec2.sh world.txt zot &&
git commit -m "files for disabled auto-props" &&
git svn dcommit --config-dir=user
'
test_expect_success 'check resulting svn repository' '
mkdir work &&
cd work &&
svn co "$svnrepo" &&
cd svnrepo &&
# Check properties from first commit.
test "x$(svn propget svn:executable exec1.sh)" = "x*" &&
test "x$(svn propget svn:mime-type exec1.sh)" = \
"xapplication/x-shellscript" &&
test "x$(svn propget svn:mime-type hello.txt)" = "xtext/plain" &&
test "x$(svn propget svn:eol-style hello.txt)" = "xnative" &&
test "x$(svn propget svn:mime-type bar)" = "x" &&
# Check properties from second commit.
test "x$(svn propget svn:executable exec2.sh)" = "x*" &&
test "x$(svn propget svn:mime-type exec2.sh)" = "x" &&
test "x$(svn propget svn:mime-type world.txt)" = "x" &&
test "x$(svn propget svn:eol-style world.txt)" = "x" &&
test "x$(svn propget svn:mime-type zot)" = "x"
'
test_done

View File

@@ -638,7 +638,7 @@ int main(int argc, char **argv)
if (i != argc-1)
usage(upload_pack_usage);
setup_path(NULL);
setup_path();
dir = argv[i];