summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apply.c18
-rw-r--r--cache.h2
-rw-r--r--checkout-index.c12
-rw-r--r--clone-pack.c2
-rw-r--r--commit-tree.c2
-rw-r--r--convert-objects.c2
-rw-r--r--fetch-pack.c2
-rw-r--r--fsck-objects.c2
-rwxr-xr-xgit-add.sh5
-rwxr-xr-xgit-branch.sh11
-rwxr-xr-xgit-count-objects.sh2
-rwxr-xr-xgit-diff.sh5
-rwxr-xr-xgit-lost-found.sh3
-rwxr-xr-xgit-ls-remote.sh5
-rwxr-xr-xgit-merge-octopus.sh5
-rwxr-xr-xgit-tag.sh7
-rwxr-xr-xgit-verify-tag.sh17
-rw-r--r--hash-object.c18
-rw-r--r--http-fetch.c2
-rw-r--r--http-push.c1
-rw-r--r--local-fetch.c2
-rw-r--r--merge-base.c2
-rw-r--r--merge-index.c1
-rw-r--r--mktag.c2
-rw-r--r--pack-objects.c2
-rw-r--r--pack-redundant.c2
-rw-r--r--peek-remote.c3
-rw-r--r--prune-packed.c2
-rw-r--r--read-tree.c2
-rw-r--r--send-pack.c1
-rw-r--r--setup.c28
-rw-r--r--ssh-fetch.c2
-rw-r--r--ssh-upload.c3
-rw-r--r--tar-tree.c2
-rw-r--r--unpack-file.c2
-rw-r--r--unpack-objects.c2
-rw-r--r--update-server-info.c2
-rw-r--r--write-tree.c5
38 files changed, 168 insertions, 20 deletions
diff --git a/apply.c b/apply.c
index 50be8f3e22..1742ab28e9 100644
--- a/apply.c
+++ b/apply.c
@@ -16,6 +16,9 @@
// --numstat does numeric diffstat, and doesn't actually apply
// --index-info shows the old and new index info for paths if available.
//
+static const char *prefix;
+static int prefix_length = -1;
+
static int allow_binary_replacement = 0;
static int check_index = 0;
static int write_index = 0;
@@ -1706,6 +1709,12 @@ static int use_patch(struct patch *p)
return 0;
x = x->next;
}
+ if (0 < prefix_length) {
+ int pathlen = strlen(pathname);
+ if (pathlen <= prefix_length ||
+ memcmp(prefix, pathname, prefix_length))
+ return 0;
+ }
return 1;
}
@@ -1845,6 +1854,15 @@ int main(int argc, char **argv)
line_termination = 0;
continue;
}
+
+ if (check_index && prefix_length < 0) {
+ prefix = setup_git_directory();
+ prefix_length = prefix ? strlen(prefix) : 0;
+ git_config(git_default_config);
+ }
+ if (0 < prefix_length)
+ arg = prefix_filename(prefix, prefix_length, arg);
+
fd = open(arg, O_RDONLY);
if (fd < 0)
usage(apply_usage);
diff --git a/cache.h b/cache.h
index 634b5aa69c..f9b367f314 100644
--- a/cache.h
+++ b/cache.h
@@ -147,8 +147,10 @@ extern char *get_graft_file(void);
#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
extern const char **get_pathspec(const char *prefix, const char **pathspec);
+extern const char *setup_git_directory_gently(int *);
extern const char *setup_git_directory(void);
extern const char *prefix_path(const char *prefix, int len, const char *path);
+extern const char *prefix_filename(const char *prefix, int len, const char *path);
#define alloc_nr(x) (((x)+16)*3/2)
diff --git a/checkout-index.c b/checkout-index.c
index dab3778a95..f1e716d412 100644
--- a/checkout-index.c
+++ b/checkout-index.c
@@ -34,6 +34,9 @@
*/
#include "cache.h"
+static const char *prefix;
+static int prefix_length;
+
static struct checkout state = {
.base_dir = "",
.base_dir_len = 0,
@@ -69,6 +72,10 @@ static int checkout_all(void)
struct cache_entry *ce = active_cache[i];
if (ce_stage(ce))
continue;
+ if (prefix && *prefix &&
+ ( ce_namelen(ce) <= prefix_length ||
+ memcmp(prefix, ce->name, prefix_length) ))
+ continue;
if (checkout_entry(ce, &state) < 0)
errs++;
}
@@ -91,6 +98,9 @@ int main(int argc, char **argv)
int newfd = -1;
int all = 0;
+ prefix = setup_git_directory();
+ prefix_length = prefix ? strlen(prefix) : 0;
+
if (read_cache() < 0) {
die("invalid cache");
}
@@ -155,7 +165,7 @@ int main(int argc, char **argv)
if (all)
die("git-checkout-index: don't mix '--all' and explicit filenames");
- checkout_file(arg);
+ checkout_file(prefix_path(prefix, prefix_length, arg));
}
if (all)
diff --git a/clone-pack.c b/clone-pack.c
index 960921903e..a99a95c5f2 100644
--- a/clone-pack.c
+++ b/clone-pack.c
@@ -271,6 +271,8 @@ int main(int argc, char **argv)
int fd[2];
pid_t pid;
+ setup_git_directory();
+
nr_heads = 0;
heads = NULL;
for (i = 1; i < argc; i++) {
diff --git a/commit-tree.c b/commit-tree.c
index b60299fed0..4634b50e6a 100644
--- a/commit-tree.c
+++ b/commit-tree.c
@@ -91,6 +91,8 @@ int main(int argc, char **argv)
if (argc < 2 || get_sha1_hex(argv[1], tree_sha1) < 0)
usage(commit_tree_usage);
+ setup_git_directory();
+
check_valid(tree_sha1, "tree");
for (i = 2; i < argc; i += 2) {
char *a, *b;
diff --git a/convert-objects.c b/convert-objects.c
index a892013f0f..d78a8b4ae3 100644
--- a/convert-objects.c
+++ b/convert-objects.c
@@ -316,6 +316,8 @@ int main(int argc, char **argv)
unsigned char sha1[20];
struct entry *entry;
+ setup_git_directory();
+
if (argc != 2 || get_sha1(argv[1], sha1))
usage("git-convert-objects <sha1>");
diff --git a/fetch-pack.c b/fetch-pack.c
index 6565982660..58ba2094dc 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -424,6 +424,8 @@ int main(int argc, char **argv)
int fd[2];
pid_t pid;
+ setup_git_directory();
+
nr_heads = 0;
heads = NULL;
for (i = 1; i < argc; i++) {
diff --git a/fsck-objects.c b/fsck-objects.c
index 0433a1d0da..90e638e573 100644
--- a/fsck-objects.c
+++ b/fsck-objects.c
@@ -431,6 +431,8 @@ int main(int argc, char **argv)
{
int i, heads;
+ setup_git_directory();
+
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
diff --git a/git-add.sh b/git-add.sh
index b5fe46aa20..fdec86d1a4 100755
--- a/git-add.sh
+++ b/git-add.sh
@@ -1,5 +1,10 @@
#!/bin/sh
+die () {
+ echo >&2 "$*"
+ exit 1
+}
+
usage() {
die "usage: git add [-n] [-v] <file>..."
}
diff --git a/git-branch.sh b/git-branch.sh
index 4cd5da16f7..5306b2719f 100755
--- a/git-branch.sh
+++ b/git-branch.sh
@@ -1,6 +1,11 @@
#!/bin/sh
-. git-sh-setup
+GIT_DIR=`git-rev-parse --git-dir` || exit $?
+
+die () {
+ echo >&2 "$*"
+ exit 1
+}
usage () {
echo >&2 "usage: $(basename $0)"' [-d <branch>] | [[-f] <branch> [start-point]]
@@ -12,8 +17,7 @@ If two arguments, create a new branch <branchname> based off of <start-point>.
exit 1
}
-headref=$(GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD |
- sed -e 's|^refs/heads/||')
+headref=$(git-symbolic-ref HEAD | sed -e 's|^refs/heads/||')
delete_branch () {
option="$1"
@@ -114,4 +118,3 @@ then
fi
fi
git update-ref "refs/heads/$branchname" $rev
-
diff --git a/git-count-objects.sh b/git-count-objects.sh
index d6e9a3221f..40c58efe08 100755
--- a/git-count-objects.sh
+++ b/git-count-objects.sh
@@ -3,7 +3,7 @@
# Copyright (c) 2005 Junio C Hamano
#
-. git-sh-setup
+GIT_DIR=`git-rev-parse --git-dir` || exit $?
dc </dev/null 2>/dev/null || {
# This is not a real DC at all -- it just knows how
diff --git a/git-diff.sh b/git-diff.sh
index 7baf7044e4..b62e58341c 100755
--- a/git-diff.sh
+++ b/git-diff.sh
@@ -7,6 +7,11 @@ rev=$(git-rev-parse --revs-only --no-flags --sq "$@") || exit
flags=$(git-rev-parse --no-revs --flags --sq "$@")
files=$(git-rev-parse --no-revs --no-flags --sq "$@")
+die () {
+ echo >&2 "$*"
+ exit 1
+}
+
# I often say 'git diff --cached -p' and get scolded by git-diff-files, but
# obviously I mean 'git diff --cached -p HEAD' in that case.
case "$rev" in
diff --git a/git-lost-found.sh b/git-lost-found.sh
index 9dd7430018..2beec2aa63 100755
--- a/git-lost-found.sh
+++ b/git-lost-found.sh
@@ -1,7 +1,6 @@
#!/bin/sh
-. git-sh-setup
-
+GIT_DIR=`git-rev-parse --git-dir` || exit $?
laf="$GIT_DIR/lost-found"
rm -fr "$laf" && mkdir -p "$laf/commit" "$laf/other" || exit
diff --git a/git-ls-remote.sh b/git-ls-remote.sh
index dc6a775a9b..f69926862f 100755
--- a/git-ls-remote.sh
+++ b/git-ls-remote.sh
@@ -6,6 +6,11 @@ usage () {
exit 1;
}
+die () {
+ echo >&2 "$*"
+ exit 1
+}
+
while case "$#" in 0) break;; esac
do
case "$1" in
diff --git a/git-merge-octopus.sh b/git-merge-octopus.sh
index bb58e22a18..7adffdc795 100755
--- a/git-merge-octopus.sh
+++ b/git-merge-octopus.sh
@@ -8,6 +8,11 @@
LF='
'
+die () {
+ echo >&2 "$*"
+ exit 1
+}
+
# The first parameters up to -- are merge bases; the rest are heads.
bases= head= remotes= sep_seen=
for arg
diff --git a/git-tag.sh b/git-tag.sh
index 16efc5b70a..2435a75f7a 100755
--- a/git-tag.sh
+++ b/git-tag.sh
@@ -1,13 +1,18 @@
#!/bin/sh
# Copyright (c) 2005 Linus Torvalds
-. git-sh-setup
+GIT_DIR=`git-rev-parse --git-dir` || exit $?
usage () {
echo >&2 "Usage: git-tag [-a | -s | -u <key-id>] [-f | -d] [-m <msg>] <tagname> [<head>]"
exit 1
}
+die () {
+ echo >&2 "$*"
+ exit 1
+}
+
annotate=
signed=
force=
diff --git a/git-verify-tag.sh b/git-verify-tag.sh
index 3c65f4a6b5..1f44da5349 100755
--- a/git-verify-tag.sh
+++ b/git-verify-tag.sh
@@ -1,5 +1,11 @@
#!/bin/sh
-. git-sh-setup
+
+GIT_DIR=`git-rev-parse --git-dir` || exit $?
+
+die () {
+ echo >&2 "$*"
+ exit 1
+}
type="$(git-cat-file -t "$1" 2>/dev/null)" ||
die "$1: no such object."
@@ -7,6 +13,9 @@ type="$(git-cat-file -t "$1" 2>/dev/null)" ||
test "$type" = tag ||
die "$1: cannot verify a non-tag object of type $type."
-git-cat-file tag "$1" > .tmp-vtag || exit 1
-cat .tmp-vtag | sed '/-----BEGIN PGP/Q' | gpg --verify .tmp-vtag - || exit 1
-rm -f .tmp-vtag
+git-cat-file tag "$1" >"$GIT_DIR/.tmp-vtag" || exit 1
+cat "$GIT_DIR/.tmp-vtag" |
+sed '/-----BEGIN PGP/Q' |
+gpg --verify "$GIT_DIR/.tmp-vtag" - || exit 1
+rm -f "$GIT_DIR/.tmp-vtag"
+
diff --git a/hash-object.c b/hash-object.c
index c8c9adb3aa..ccba11cb32 100644
--- a/hash-object.c
+++ b/hash-object.c
@@ -29,6 +29,8 @@ int main(int argc, char **argv)
int i;
const char *type = "blob";
int write_object = 0;
+ const char *prefix = NULL;
+ int prefix_length = -1;
for (i = 1 ; i < argc; i++) {
if (!strcmp(argv[i], "-t")) {
@@ -36,10 +38,20 @@ int main(int argc, char **argv)
die(hash_object_usage);
type = argv[i];
}
- else if (!strcmp(argv[i], "-w"))
+ else if (!strcmp(argv[i], "-w")) {
+ if (prefix_length < 0) {
+ prefix = setup_git_directory();
+ prefix_length = prefix ? strlen(prefix) : 0;
+ }
write_object = 1;
- else
- hash_object(argv[i], type, write_object);
+ }
+ else {
+ const char *arg = argv[i];
+ if (0 <= prefix_length)
+ arg = prefix_filename(prefix, prefix_length,
+ arg);
+ hash_object(arg, type, write_object);
+ }
}
return 0;
}
diff --git a/http-fetch.c b/http-fetch.c
index 435317342b..ad59f1cce6 100644
--- a/http-fetch.c
+++ b/http-fetch.c
@@ -922,6 +922,8 @@ int main(int argc, char **argv)
int arg = 1;
int rc = 0;
+ setup_git_directory();
+
while (arg < argc && argv[arg][0] == '-') {
if (argv[arg][1] == 't') {
get_tree = 1;
diff --git a/http-push.c b/http-push.c
index fc013ec139..fe925609b4 100644
--- a/http-push.c
+++ b/http-push.c
@@ -1237,6 +1237,7 @@ int main(int argc, char **argv)
int rc = 0;
int i;
+ setup_git_directory();
setup_ident();
remote = xmalloc(sizeof(*remote));
diff --git a/local-fetch.c b/local-fetch.c
index 0931109143..fa9e697fd3 100644
--- a/local-fetch.c
+++ b/local-fetch.c
@@ -207,6 +207,8 @@ int main(int argc, char **argv)
char *commit_id;
int arg = 1;
+ setup_git_directory();
+
while (arg < argc && argv[arg][0] == '-') {
if (argv[arg][1] == 't')
get_tree = 1;
diff --git a/merge-base.c b/merge-base.c
index 751c3c281b..e73fca7453 100644
--- a/merge-base.c
+++ b/merge-base.c
@@ -236,6 +236,8 @@ int main(int argc, char **argv)
struct commit *rev1, *rev2;
unsigned char rev1key[20], rev2key[20];
+ setup_git_directory();
+
while (1 < argc && argv[1][0] == '-') {
char *arg = argv[1];
if (!strcmp(arg, "-a") || !strcmp(arg, "--all"))
diff --git a/merge-index.c b/merge-index.c
index 727527fd59..024196e7ac 100644
--- a/merge-index.c
+++ b/merge-index.c
@@ -102,6 +102,7 @@ int main(int argc, char **argv)
if (argc < 3)
usage("git-merge-index [-o] [-q] <merge-program> (-a | <filename>*)");
+ setup_git_directory();
read_cache();
i = 1;
diff --git a/mktag.c b/mktag.c
index 585677eb83..97e270a576 100644
--- a/mktag.c
+++ b/mktag.c
@@ -111,6 +111,8 @@ int main(int argc, char **argv)
if (argc != 1)
usage("cat <signaturefile> | git-mktag");
+ setup_git_directory();
+
// Read the signature
size = 0;
for (;;) {
diff --git a/pack-objects.c b/pack-objects.c
index 8864a31cc1..a62c9f8d18 100644
--- a/pack-objects.c
+++ b/pack-objects.c
@@ -473,6 +473,8 @@ int main(int argc, char **argv)
struct object_entry **list;
int i;
+ setup_git_directory();
+
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
diff --git a/pack-redundant.c b/pack-redundant.c
index 793fa08096..0a43278924 100644
--- a/pack-redundant.c
+++ b/pack-redundant.c
@@ -600,6 +600,8 @@ int main(int argc, char **argv)
unsigned char *sha1;
char buf[42]; /* 40 byte sha1 + \n + \0 */
+ setup_git_directory();
+
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
if(!strcmp(arg, "--")) {
diff --git a/peek-remote.c b/peek-remote.c
index ee49bf3b7b..a90cf22069 100644
--- a/peek-remote.c
+++ b/peek-remote.c
@@ -27,6 +27,9 @@ int main(int argc, char **argv)
char *dest = NULL;
int fd[2];
pid_t pid;
+ int nongit = 0;
+
+ setup_git_directory_gently(&nongit);
for (i = 1; i < argc; i++) {
char *arg = argv[i];
diff --git a/prune-packed.c b/prune-packed.c
index 26123f7f6b..d24b097114 100644
--- a/prune-packed.c
+++ b/prune-packed.c
@@ -58,6 +58,8 @@ int main(int argc, char **argv)
{
int i;
+ setup_git_directory();
+
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
diff --git a/read-tree.c b/read-tree.c
index df156ea0da..e3b9c0d9fa 100644
--- a/read-tree.c
+++ b/read-tree.c
@@ -629,6 +629,8 @@ int main(int argc, char **argv)
unsigned char sha1[20];
merge_fn_t fn = NULL;
+ setup_git_directory();
+
newfd = hold_index_file_for_update(&cache_file, get_index_file());
if (newfd < 0)
die("unable to create new cachefile");
diff --git a/send-pack.c b/send-pack.c
index 3eeb18f7c7..2a14b00845 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -273,6 +273,7 @@ int main(int argc, char **argv)
int fd[2], ret;
pid_t pid;
+ setup_git_directory();
argv++;
for (i = 1; i < argc; i++, argv++) {
char *arg = *argv;
diff --git a/setup.c b/setup.c
index 3286a568ed..d3556edf12 100644
--- a/setup.c
+++ b/setup.c
@@ -47,6 +47,21 @@ const char *prefix_path(const char *prefix, int len, const char *path)
return path;
}
+/*
+ * Unlike prefix_path, this should be used if the named file does
+ * not have to interact with index entry; i.e. name of a random file
+ * on the filesystem.
+ */
+const char *prefix_filename(const char *pfx, int pfx_len, const char *arg)
+{
+ static char path[PATH_MAX];
+ if (!pfx || !*pfx || arg[0] == '/')
+ return arg;
+ memcpy(path, pfx, pfx_len);
+ strcpy(path + pfx_len, arg);
+ return path;
+}
+
const char **get_pathspec(const char *prefix, const char **pathspec)
{
const char *entry = *pathspec;
@@ -92,7 +107,7 @@ static int is_toplevel_directory(void)
return 1;
}
-static const char *setup_git_directory_1(void)
+const char *setup_git_directory_gently(int *nongit_ok)
{
static char cwd[PATH_MAX+1];
int len, offset;
@@ -139,8 +154,15 @@ static const char *setup_git_directory_1(void)
break;
chdir("..");
do {
- if (!offset)
+ if (!offset) {
+ if (nongit_ok) {
+ if (chdir(cwd))
+ die("Cannot come back to cwd");
+ *nongit_ok = 1;
+ return NULL;
+ }
die("Not a git repository");
+ }
} while (cwd[--offset] != '/');
}
@@ -172,7 +194,7 @@ int check_repository_format(void)
const char *setup_git_directory(void)
{
- const char *retval = setup_git_directory_1();
+ const char *retval = setup_git_directory_gently(NULL);
check_repository_format();
return retval;
}
diff --git a/ssh-fetch.c b/ssh-fetch.c
index bf01fbc00d..4eb9e04829 100644
--- a/ssh-fetch.c
+++ b/ssh-fetch.c
@@ -131,6 +131,8 @@ int main(int argc, char **argv)
prog = getenv("GIT_SSH_PUSH");
if (!prog) prog = "git-ssh-upload";
+ setup_git_directory();
+
while (arg < argc && argv[arg][0] == '-') {
if (argv[arg][1] == 't') {
get_tree = 1;
diff --git a/ssh-upload.c b/ssh-upload.c
index 603abcc8c3..b675a0b1f1 100644
--- a/ssh-upload.c
+++ b/ssh-upload.c
@@ -121,6 +121,9 @@ int main(int argc, char **argv)
prog = getenv(COUNTERPART_ENV_NAME);
if (!prog) prog = COUNTERPART_PROGRAM_NAME;
+
+ setup_git_directory();
+
while (arg < argc && argv[arg][0] == '-') {
if (argv[arg][1] == 'w')
arg++;
diff --git a/tar-tree.c b/tar-tree.c
index 970c4bb54e..bacb23ae63 100644
--- a/tar-tree.c
+++ b/tar-tree.c
@@ -407,6 +407,8 @@ int main(int argc, char **argv)
void *buffer;
unsigned long size;
+ setup_git_directory();
+
switch (argc) {
case 3:
basedir = argv[2];
diff --git a/unpack-file.c b/unpack-file.c
index d4ac3a5460..07303f8bb3 100644
--- a/unpack-file.c
+++ b/unpack-file.c
@@ -29,6 +29,8 @@ int main(int argc, char **argv)
if (argc != 2 || get_sha1(argv[1], sha1))
usage("git-unpack-file <sha1>");
+ setup_git_directory();
+
puts(create_temp_file(sha1));
return 0;
}
diff --git a/unpack-objects.c b/unpack-objects.c
index 8490895cf0..cfd61ae6b0 100644
--- a/unpack-objects.c
+++ b/unpack-objects.c
@@ -269,6 +269,8 @@ int main(int argc, char **argv)
int i;
unsigned char sha1[20];
+ setup_git_directory();
+
for (i = 1 ; i < argc; i++) {
const char *arg = argv[i];
diff --git a/update-server-info.c b/update-server-info.c
index e824f62eaf..0b6c3835bd 100644
--- a/update-server-info.c
+++ b/update-server-info.c
@@ -19,5 +19,7 @@ int main(int ac, char **av)
if (i != ac)
usage(update_server_info_usage);
+ setup_git_directory();
+
return !!update_server_info(force);
}
diff --git a/write-tree.c b/write-tree.c
index 2b2c6b77af..0aac32f227 100644
--- a/write-tree.c
+++ b/write-tree.c
@@ -86,9 +86,12 @@ static int write_tree(struct cache_entry **cachep, int maxentries, const char *b
int main(int argc, char **argv)
{
int i, funny;
- int entries = read_cache();
+ int entries;
unsigned char sha1[20];
+ setup_git_directory();
+
+ entries = read_cache();
if (argc == 2) {
if (!strcmp(argv[1], "--missing-ok"))
missing_ok = 1;