mirror of
https://github.com/git/git.git
synced 2026-03-13 10:23:30 +01:00
Merge branch 'master' of git://repo.or.cz/alt-git
This commit is contained in:
@@ -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).
|
||||
|
||||
@@ -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
|
||||
-----------
|
||||
|
||||
@@ -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>::
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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'::
|
||||
|
||||
@@ -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>...
|
||||
|
||||
@@ -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::
|
||||
|
||||
|
||||
@@ -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`
|
||||
|
||||
59
Makefile
59
Makefile
@@ -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
|
||||
|
||||
36
abspath.c
36
abspath.c
@@ -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
159
archive.c
@@ -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);
|
||||
}
|
||||
|
||||
18
archive.h
18
archive.h
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) &&
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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, ...)
|
||||
|
||||
@@ -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);
|
||||
|
||||
13
commit.c
13
commit.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 ;;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
25
daemon.c
25
daemon.c
@@ -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
56
editor.c
Normal 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;
|
||||
}
|
||||
54
exec_cmd.c
54
exec_cmd.c
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
'')
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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, $_;
|
||||
|
||||
@@ -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
|
||||
|
||||
53
git-svn.perl
53
git-svn.perl
@@ -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
5
git.c
@@ -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 */
|
||||
|
||||
@@ -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
36
path.c
@@ -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];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) &&
|
||||
|
||||
4
shell.c
4
shell.c
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
2
strbuf.h
2
strbuf.h
@@ -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 */
|
||||
|
||||
@@ -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' '
|
||||
|
||||
@@ -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
50
t/t2010-checkout-ambiguous.sh
Executable 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
59
t/t3202-show-branch-octopus.sh
Executable 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
|
||||
@@ -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 .
|
||||
)
|
||||
|
||||
@@ -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
|
||||
'
|
||||
|
||||
@@ -71,4 +71,5 @@ test_expect_success 'diff-filter=D' '
|
||||
|
||||
|
||||
|
||||
test_done
|
||||
test_done
|
||||
|
||||
|
||||
@@ -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
26
t/t5602-clone-remote-exec.sh
Executable 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
|
||||
@@ -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
|
||||
'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
86
t/t9124-git-svn-dcommit-auto-props.sh
Executable file
86
t/t9124-git-svn-dcommit-auto-props.sh
Executable 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
|
||||
@@ -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];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user