summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/git-rev-parse.txt35
-rw-r--r--fetch.c2
-rwxr-xr-xgit-add.sh32
-rw-r--r--http-fetch.c45
-rw-r--r--rev-parse.c16
-rw-r--r--update-index.c36
6 files changed, 146 insertions, 20 deletions
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index fa64c5a..067e4f0 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -76,6 +76,41 @@ OPTIONS
Flags and parameters to be parsed.
+SPECIFYING REVISIONS
+--------------------
+
+A revision parameter typically names a commit object. They use
+what is called an 'extended SHA1' syntax.
+
+* The full SHA1 object name (40-byte hexadecimal string), or
+ a substring of such that is unique within the repository.
+ E.g. dae86e1950b1277e545cee180551750029cfe735 and dae86e both
+ name the same commit object if there are no other object in
+ your repository whose object name starts with dae86e.
+
+* A symbolic ref name. E.g. 'master' typically means the commit
+ object referenced by $GIT_DIR/refs/heads/master. If you
+ happen to have both heads/master and tags/master, you can
+ explicitly say 'heads/master' to tell GIT which one you mean.
+
+* A suffix '^' to a revision parameter means the first parent of
+ that commit object. '^<n>' means the <n>th parent (i.e.
+ 'rev^'
+ is equivalent to 'rev^1'). As a special rule,
+ 'rev^0' means the commit itself and is used when 'rev' is the
+ object name of a tag object that refers to a commit object.
+
+* A suffix '~<n>' to a revision parameter means the commit
+ object that is the <n>th generation grand-parent of the named
+ commit object, following only the first parent. I.e. rev~3 is
+ equivalent to rev^^^ which is equivalent to rev^1^1^1.
+
+'git-rev-parse' also accepts a prefix '^' to revision parameter,
+which is passed to 'git-rev-list'. Two revision parameters
+concatenated with '..' is a short-hand for writing a range
+between them. I.e. 'r1..r2' is equivalent to saying '^r1 r2'
+
+
Author
------
Written by Linus Torvalds <torvalds@osdl.org> and
diff --git a/fetch.c b/fetch.c
index 1d95ce0..af9a013 100644
--- a/fetch.c
+++ b/fetch.c
@@ -174,7 +174,7 @@ static int loop(void)
* the queue because we needed to fetch it first.
*/
if (! (obj->flags & TO_SCAN)) {
- if (fetch(obj->sha1)) {
+ if (!has_sha1_file(obj->sha1) && fetch(obj->sha1)) {
report_missing(obj->type
? obj->type
: "object", obj->sha1);
diff --git a/git-add.sh b/git-add.sh
index 7d91eeb..3d364db 100755
--- a/git-add.sh
+++ b/git-add.sh
@@ -1,2 +1,32 @@
#!/bin/sh
-git-update-index --add -- "$@"
+
+show_only=
+verbose=
+while : ; do
+ case "$1" in
+ -n)
+ show_only=true
+ verbose=true
+ ;;
+ -v)
+ verbose=true
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+done
+
+GIT_DIR=$(git-rev-parse --git-dir) || exit
+global_exclude=
+if [ -f "$GIT_DIR/info/exclude" ]; then
+ global_exclude="--exclude-from=$GIT_DIR/info/exclude"
+fi
+for i in $(git-ls-files --others \
+ $global_exclude --exclude-per-directory=.gitignore \
+ "$@")
+do
+ [ "$verbose" ] && echo " $i"
+ [ "$show_only" ] || git-update-index --add -- "$i" || exit
+done
diff --git a/http-fetch.c b/http-fetch.c
index 17051fe..77f530c 100644
--- a/http-fetch.c
+++ b/http-fetch.c
@@ -144,10 +144,11 @@ static int fetch_alternates(char *base)
char *url;
char *data;
int i = 0;
+ int http_specific = 1;
if (got_alternates)
return 0;
data = xmalloc(4096);
- buffer.size = 4096;
+ buffer.size = 4095;
buffer.posn = 0;
buffer.buffer = data;
@@ -162,6 +163,8 @@ static int fetch_alternates(char *base)
curl_easy_setopt(curl, CURLOPT_URL, url);
if (curl_easy_perform(curl) || !buffer.posn) {
+ http_specific = 0;
+
sprintf(url, "%s/objects/info/alternates", base);
curl_easy_setopt(curl, CURLOPT_FILE, &buffer);
@@ -173,17 +176,45 @@ static int fetch_alternates(char *base)
}
}
+ data[buffer.posn] = '\0';
+
while (i < buffer.posn) {
int posn = i;
while (posn < buffer.posn && data[posn] != '\n')
posn++;
if (data[posn] == '\n') {
+ int okay = 0;
+ int serverlen = 0;
+ struct alt_base *newalt;
+ char *target = NULL;
if (data[i] == '/') {
- int serverlen = strchr(base + 8, '/') - base;
- // skip 'objects' at end
- char *target =
- xmalloc(serverlen + posn - i - 6);
- struct alt_base *newalt;
+ serverlen = strchr(base + 8, '/') - base;
+ okay = 1;
+ } else if (!memcmp(data + i, "../", 3)) {
+ i += 3;
+ serverlen = strlen(base);
+ while (i + 2 < posn &&
+ !memcmp(data + i, "../", 3)) {
+ do {
+ serverlen--;
+ } while (serverlen &&
+ base[serverlen - 1] != '/');
+ i += 3;
+ }
+ // If the server got removed, give up.
+ okay = strchr(base, ':') - base + 3 <
+ serverlen;
+ } else if (http_specific) {
+ char *colon = strchr(data + i, ':');
+ char *slash = strchr(data + i, '/');
+ if (colon && slash && colon < data + posn &&
+ slash < data + posn && colon < slash) {
+ okay = 1;
+ }
+ }
+ // skip 'objects' at end
+ if (okay) {
+ target = xmalloc(serverlen + posn - i - 6);
strncpy(target, base, serverlen);
strncpy(target + serverlen, data + i,
posn - i - 7);
@@ -235,7 +266,7 @@ static int fetch_indices(struct alt_base *repo)
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, NULL);
if (curl_easy_perform(curl)) {
- return error("Unable to get pack index %s", url);
+ return -1;
}
while (i < buffer.posn) {
diff --git a/rev-parse.c b/rev-parse.c
index 6d723f9..0f5630f 100644
--- a/rev-parse.c
+++ b/rev-parse.c
@@ -191,6 +191,22 @@ int main(int argc, char **argv)
puts(prefix);
continue;
}
+ if (!strcmp(arg, "--git-dir")) {
+ const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
+ static char cwd[PATH_MAX];
+ if (gitdir) {
+ puts(gitdir);
+ continue;
+ }
+ if (!prefix) {
+ puts(".git");
+ continue;
+ }
+ if (!getcwd(cwd, PATH_MAX))
+ die("unable to get current working directory");
+ printf("%s/.git\n", cwd);
+ continue;
+ }
if (verify)
die("Needed a single revision");
show_flag(arg);
diff --git a/update-index.c b/update-index.c
index d10dfd9..8fe015b 100644
--- a/update-index.c
+++ b/update-index.c
@@ -50,11 +50,20 @@ static int add_file_to_cache(char *path)
* case just fine without --force-remove.
*/
if (status == 0 || (errno == ENOENT || errno == ENOTDIR)) {
- if (allow_remove)
- return remove_file_from_cache(path);
+ if (allow_remove) {
+ if (remove_file_from_cache(path))
+ return error("%s: cannot remove from the index",
+ path);
+ else
+ return 0;
+ } else if (status < 0) {
+ return error("%s: does not exist and --remove not passed",
+ path);
+ }
}
if (0 == status)
- return error("%s: is a directory", path);
+ return error("%s: is a directory - add files inside instead",
+ path);
else
return error("lstat(\"%s\"): %s", path,
strerror(errno));
@@ -71,15 +80,17 @@ static int add_file_to_cache(char *path)
case S_IFREG:
fd = open(path, O_RDONLY);
if (fd < 0)
- return -1;
+ return error("open(\"%s\"): %s", path, strerror(errno));
if (index_fd(ce->sha1, fd, &st, !info_only, NULL) < 0)
- return -1;
+ return error("%s: failed to insert into database", path);
break;
case S_IFLNK:
target = xmalloc(st.st_size+1);
if (readlink(path, target, st.st_size+1) != st.st_size) {
+ char *errstr = strerror(errno);
free(target);
- return -1;
+ return error("readlink(\"%s\"): %s", path,
+ errstr);
}
if (info_only) {
unsigned char hdr[50];
@@ -87,15 +98,18 @@ static int add_file_to_cache(char *path)
write_sha1_file_prepare(target, st.st_size, "blob",
ce->sha1, hdr, &hdrlen);
} else if (write_sha1_file(target, st.st_size, "blob", ce->sha1))
- return -1;
+ return error("%s: failed to insert into database", path);
free(target);
break;
default:
- return -1;
+ return error("%s: unsupported file type", path);
}
option = allow_add ? ADD_CACHE_OK_TO_ADD : 0;
option |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0;
- return add_cache_entry(ce, option);
+ if (add_cache_entry(ce, option))
+ return error("%s: cannot add to the index - missing --add option?",
+ path);
+ return 0;
}
static int compare_data(struct cache_entry *ce, struct stat *st)
@@ -393,11 +407,11 @@ int main(int argc, char **argv)
}
if (force_remove) {
if (remove_file_from_cache(path))
- die("git-update-index: --force-remove cannot remove %s", path);
+ die("git-update-index: unable to remove %s", path);
continue;
}
if (add_file_to_cache(path))
- die("Unable to add %s to database; maybe you want to use --add option?", path);
+ die("Unable to process file %s", path);
}
if (write_cache(newfd, active_cache, active_nr) ||
commit_index_file(&cache_file))