summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/Makefile1
-rw-r--r--Documentation/asciidoc.conf2
-rw-r--r--Documentation/config.txt15
-rw-r--r--Documentation/git-cvsexportcommit.txt8
-rw-r--r--Documentation/git-tar-tree.txt15
-rw-r--r--Documentation/urls.txt17
-rw-r--r--Makefile30
-rw-r--r--blob.c6
-rw-r--r--builtin-diff.c6
-rw-r--r--builtin-fmt-merge-msg.c2
-rw-r--r--builtin-grep.c4
-rw-r--r--builtin-prune.c6
-rw-r--r--builtin-rev-list.c6
-rw-r--r--builtin-show-branch.c11
-rw-r--r--builtin-tar-tree.c21
-rw-r--r--commit.c6
-rw-r--r--contrib/emacs/git.el31
-rw-r--r--describe.c2
-rw-r--r--diff.c28
-rw-r--r--diff.h11
-rw-r--r--fetch-pack.c10
-rw-r--r--fetch.c8
-rw-r--r--fsck-objects.c10
-rwxr-xr-xgit-am.sh12
-rwxr-xr-xgit-cvsexportcommit.perl50
-rwxr-xr-xgit-fetch.sh8
-rwxr-xr-xgit-merge.sh17
-rwxr-xr-xgit-pull.sh3
-rwxr-xr-xgit-quiltimport.sh2
-rwxr-xr-xgit-rebase.sh9
-rwxr-xr-xgit-resolve.sh7
-rwxr-xr-xgit-svn.perl25
-rw-r--r--git.c11
-rw-r--r--http-push.c12
-rw-r--r--log-tree.c5
-rw-r--r--name-rev.c8
-rw-r--r--object.c7
-rw-r--r--object.h23
-rw-r--r--pack-objects.c13
-rw-r--r--pack.h15
-rw-r--r--revision.c12
-rw-r--r--send-pack.c4
-rw-r--r--server-info.c2
-rw-r--r--sha1_file.c26
-rw-r--r--sha1_name.c12
-rwxr-xr-xt/t6004-rev-list-path-optim.sh19
-rw-r--r--tag.c8
-rw-r--r--tree.c12
-rw-r--r--unpack-objects.c5
-rw-r--r--upload-pack.c6
50 files changed, 385 insertions, 204 deletions
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 2b0efe7921..6dbe45b506 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -46,6 +46,7 @@ all: html man
html: $(DOC_HTML)
+$(DOC_HTML) $(DOC_MAN1) $(DOC_MAN7): asciidoc.conf
man: man1 man7
man1: $(DOC_MAN1)
diff --git a/Documentation/asciidoc.conf b/Documentation/asciidoc.conf
index 7ce71510de..8196d787ab 100644
--- a/Documentation/asciidoc.conf
+++ b/Documentation/asciidoc.conf
@@ -9,6 +9,8 @@
[attributes]
caret=^
+startsb=[
+endsb=]
ifdef::backend-docbook[]
[gitlink-inlinemacro]
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 9780c89bc3..465eb13e76 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -199,6 +199,10 @@ merge.summary::
Whether to include summaries of merged commits in newly created
merge commit messages. False by default.
+pack.window::
+ The size of the window used by gitlink:git-pack-objects[1] when no
+ window size is given on the command line. Defaults to 10.
+
pull.octopus::
The default merge strategy to use when pulling multiple branches
at once.
@@ -214,6 +218,17 @@ showbranch.default::
The default set of branches for gitlink:git-show-branch[1].
See gitlink:git-show-branch[1].
+tar.umask::
+ By default, git-link:git-tar-tree[1] sets file and directories modes
+ to 0666 or 0777. While this is both useful and acceptable for projects
+ such as the Linux Kernel, it might be excessive for other projects.
+ With this variable, it becomes possible to tell
+ git-link:git-tar-tree[1] to apply a specific umask to the modes above.
+ The special value "user" indicates that the user's current umask will
+ be used. This should be enough for most projects, as it will lead to
+ the same permissions as git-link:git-checkout[1] would use. The default
+ value remains 0, which means world read-write.
+
user.email::
Your email address to be recorded in any newly created commits.
Can be overridden by the 'GIT_AUTHOR_EMAIL' and 'GIT_COMMITTER_EMAIL'
diff --git a/Documentation/git-cvsexportcommit.txt b/Documentation/git-cvsexportcommit.txt
index 27ac72d98f..092d0d6730 100644
--- a/Documentation/git-cvsexportcommit.txt
+++ b/Documentation/git-cvsexportcommit.txt
@@ -8,7 +8,7 @@ git-cvsexportcommit - Export a commit to a CVS checkout
SYNOPSIS
--------
-'git-cvsexportcommit' [-h] [-v] [-c] [-p] [-f] [-m msgprefix] [PARENTCOMMIT] COMMITID
+'git-cvsexportcommit' [-h] [-v] [-c] [-p] [-a] [-f] [-m msgprefix] [PARENTCOMMIT] COMMITID
DESCRIPTION
@@ -36,9 +36,13 @@ OPTIONS
commit if any hunks fail to apply or there were other problems.
-p::
- Be pedantic (paranoid) when applying patches. Invokes patch with
+ Be pedantic (paranoid) when applying patches. Invokes patch with
--fuzz=0
+-a::
+ Add authorship information. Adds Author line, and Committer (if
+ different from Author) to the message.
+
-f::
Force the merge even if the files are not up to date.
diff --git a/Documentation/git-tar-tree.txt b/Documentation/git-tar-tree.txt
index f2675c4193..7a99acf2ec 100644
--- a/Documentation/git-tar-tree.txt
+++ b/Documentation/git-tar-tree.txt
@@ -37,7 +37,20 @@ OPTIONS
Instead of making a tar archive from local repository,
retrieve a tar archive from a remote repository.
-Examples
+CONFIGURATION
+-------------
+By default, file and directories modes are set to 0666 or 0777. It is
+possible to change this by setting the "umask" variable in the
+repository configuration as follows :
+
+[tar]
+ umask = 002 ;# group friendly
+
+The special umask value "user" indicates that the user's current umask
+will be used instead. The default value remains 0, which means world
+readable/writable files and directories.
+
+EXAMPLES
--------
git tar-tree HEAD junk | (cd /var/tmp/ && tar xf -)::
diff --git a/Documentation/urls.txt b/Documentation/urls.txt
index 93378d2378..26ecba53fb 100644
--- a/Documentation/urls.txt
+++ b/Documentation/urls.txt
@@ -10,20 +10,21 @@ to name the remote repository:
- https://host.xz/path/to/repo.git/
- git://host.xz/path/to/repo.git/
- git://host.xz/~user/path/to/repo.git/
-- ssh://+++[user@+++]host.xz/path/to/repo.git/
-- ssh://+++[user@+++]host.xz/~user/path/to/repo.git/
-- ssh://+++[user@+++]host.xz/~/path/to/repo.git
+- ssh://{startsb}user@{endsb}host.xz/path/to/repo.git/
+- ssh://{startsb}user@{endsb}host.xz/~user/path/to/repo.git/
+- ssh://{startsb}user@{endsb}host.xz/~/path/to/repo.git
===============================================================
-SSH Is the default transport protocol and also supports an
-scp-like syntax. Both syntaxes support username expansion,
+SSH is the default transport protocol. You can optionally specify
+which user to log-in as, and an alternate, scp-like syntax is also
+supported. Both syntaxes support username expansion,
as does the native git protocol. The following three are
identical to the last three above, respectively:
===============================================================
-- host.xz:/path/to/repo.git/
-- host.xz:~user/path/to/repo.git/
-- host.xz:path/to/repo.git
+- {startsb}user@{endsb}host.xz:/path/to/repo.git/
+- {startsb}user@{endsb}host.xz:~user/path/to/repo.git/
+- {startsb}user@{endsb}host.xz:path/to/repo.git
===============================================================
To sync with a local directory, use:
diff --git a/Makefile b/Makefile
index 01fb9cfdbd..3e085dfa6f 100644
--- a/Makefile
+++ b/Makefile
@@ -37,6 +37,18 @@ all:
# tests. These tests take up a significant amount of the total test time
# but are not needed unless you plan to talk to SVN repos.
#
+# Define NO_FINK if you are building on Darwin/Mac OS X, have Fink
+# installed in /sw, but don't want GIT to link against any libraries
+# installed there. If defined you may specify your own (or Fink's)
+# include directories and library directories by defining CFLAGS
+# and LDFLAGS appropriately.
+#
+# Define NO_DARWIN_PORTS if you are building on Darwin/Mac OS X,
+# have DarwinPorts installed in /opt/local, but don't want GIT to
+# link against any libraries installed there. If defined you may
+# specify your own (or DarwinPort's) include directories and
+# library directories by defining CFLAGS and LDFLAGS appropriately.
+#
# Define PPC_SHA1 environment variable when running make to make use of
# a bundled SHA1 routine optimized for PowerPC.
#
@@ -254,15 +266,17 @@ ifeq ($(uname_S),Darwin)
NEEDS_SSL_WITH_CRYPTO = YesPlease
NEEDS_LIBICONV = YesPlease
NO_STRLCPY = YesPlease
- ## fink
- ifeq ($(shell test -d /sw/lib && echo y),y)
- ALL_CFLAGS += -I/sw/include
- ALL_LDFLAGS += -L/sw/lib
+ ifndef NO_FINK
+ ifeq ($(shell test -d /sw/lib && echo y),y)
+ ALL_CFLAGS += -I/sw/include
+ ALL_LDFLAGS += -L/sw/lib
+ endif
endif
- ## darwinports
- ifeq ($(shell test -d /opt/local/lib && echo y),y)
- ALL_CFLAGS += -I/opt/local/include
- ALL_LDFLAGS += -L/opt/local/lib
+ ifndef NO_DARWIN_PORTS
+ ifeq ($(shell test -d /opt/local/lib && echo y),y)
+ ALL_CFLAGS += -I/opt/local/include
+ ALL_LDFLAGS += -L/opt/local/lib
+ endif
endif
endif
ifeq ($(uname_S),SunOS)
diff --git a/blob.c b/blob.c
index 496f270043..d1af2e62f1 100644
--- a/blob.c
+++ b/blob.c
@@ -10,12 +10,12 @@ struct blob *lookup_blob(const unsigned char *sha1)
if (!obj) {
struct blob *ret = alloc_blob_node();
created_object(sha1, &ret->object);
- ret->object.type = TYPE_BLOB;
+ ret->object.type = OBJ_BLOB;
return ret;
}
if (!obj->type)
- obj->type = TYPE_BLOB;
- if (obj->type != TYPE_BLOB) {
+ obj->type = OBJ_BLOB;
+ if (obj->type != OBJ_BLOB) {
error("Object %s is a %s, not a blob",
sha1_to_hex(sha1), typename(obj->type));
return NULL;
diff --git a/builtin-diff.c b/builtin-diff.c
index ae901dd25e..cb38f44561 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -285,9 +285,9 @@ int cmd_diff(int argc, const char **argv, char **envp)
obj = deref_tag(obj, NULL, 0);
if (!obj)
die("invalid object '%s' given.", name);
- if (obj->type == TYPE_COMMIT)
+ if (obj->type == OBJ_COMMIT)
obj = &((struct commit *)obj)->tree->object;
- if (obj->type == TYPE_TREE) {
+ if (obj->type == OBJ_TREE) {
if (ARRAY_SIZE(ent) <= ents)
die("more than %d trees given: '%s'",
(int) ARRAY_SIZE(ent), name);
@@ -297,7 +297,7 @@ int cmd_diff(int argc, const char **argv, char **envp)
ents++;
continue;
}
- if (obj->type == TYPE_BLOB) {
+ if (obj->type == OBJ_BLOB) {
if (2 <= blobs)
die("more than two blobs given: '%s'", name);
memcpy(blob[blobs].sha1, obj->sha1, 20);
diff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c
index fe0ef44b40..f20b27b8a9 100644
--- a/builtin-fmt-merge-msg.c
+++ b/builtin-fmt-merge-msg.c
@@ -181,7 +181,7 @@ static void shortlog(const char *name, unsigned char *sha1,
int flags = UNINTERESTING | TREECHANGE | SEEN | SHOWN | ADDED;
branch = deref_tag(parse_object(sha1), sha1_to_hex(sha1), 40);
- if (!branch || branch->type != TYPE_COMMIT)
+ if (!branch || branch->type != OBJ_COMMIT)
return;
setup_revisions(0, NULL, rev, NULL);
diff --git a/builtin-grep.c b/builtin-grep.c
index 4c2f7dfe03..a79bac305a 100644
--- a/builtin-grep.c
+++ b/builtin-grep.c
@@ -891,9 +891,9 @@ static int grep_tree(struct grep_opt *opt, const char **paths,
static int grep_object(struct grep_opt *opt, const char **paths,
struct object *obj, const char *name)
{
- if (obj->type == TYPE_BLOB)
+ if (obj->type == OBJ_BLOB)
return grep_sha1(opt, obj->sha1, name);
- if (obj->type == TYPE_COMMIT || obj->type == TYPE_TREE) {
+ if (obj->type == OBJ_COMMIT || obj->type == OBJ_TREE) {
struct tree_desc tree;
void *data;
int hit;
diff --git a/builtin-prune.c b/builtin-prune.c
index ebdecee928..d196c41f13 100644
--- a/builtin-prune.c
+++ b/builtin-prune.c
@@ -158,15 +158,15 @@ static void walk_commit_list(struct rev_info *revs)
struct object_array_entry *pending = revs->pending.objects + i;
struct object *obj = pending->item;
const char *name = pending->name;
- if (obj->type == TYPE_TAG) {
+ if (obj->type == OBJ_TAG) {
process_tag((struct tag *) obj, &objects, name);
continue;
}
- if (obj->type == TYPE_TREE) {
+ if (obj->type == OBJ_TREE) {
process_tree((struct tree *)obj, &objects, NULL, name);
continue;
}
- if (obj->type == TYPE_BLOB) {
+ if (obj->type == OBJ_BLOB) {
process_blob((struct blob *)obj, &objects, NULL, name);
continue;
}
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 63bad0e96a..8f32871337 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -167,16 +167,16 @@ static void show_commit_list(struct rev_info *revs)
const char *name = pending->name;
if (obj->flags & (UNINTERESTING | SEEN))
continue;
- if (obj->type == TYPE_TAG) {
+ if (obj->type == OBJ_TAG) {
obj->flags |= SEEN;
add_object_array(obj, name, &objects);
continue;
}
- if (obj->type == TYPE_TREE) {
+ if (obj->type == OBJ_TREE) {
process_tree((struct tree *)obj, &objects, NULL, name);
continue;
}
- if (obj->type == TYPE_BLOB) {
+ if (obj->type == OBJ_BLOB) {
process_blob((struct blob *)obj, &objects, NULL, name);
continue;
}
diff --git a/builtin-show-branch.c b/builtin-show-branch.c
index 260cb221b9..82f75b72de 100644
--- a/builtin-show-branch.c
+++ b/builtin-show-branch.c
@@ -89,6 +89,8 @@ static int name_first_parent_chain(struct commit *c)
name_parent(c, p);
i++;
}
+ else
+ break;
c = p;
}
return i;
@@ -172,7 +174,7 @@ static void name_commits(struct commit_list *list,
static int mark_seen(struct commit *commit, struct commit_list **seen_p)
{
if (!commit->object.flags) {
- insert_by_date(commit, seen_p);
+ commit_list_insert(commit, seen_p);
return 1;
}
return 0;
@@ -218,9 +220,8 @@ static void join_revs(struct commit_list **list_p,
* Postprocess to complete well-poisoning.
*
* At this point we have all the commits we have seen in
- * seen_p list (which happens to be sorted chronologically but
- * it does not really matter). Mark anything that can be
- * reached from uninteresting commits not interesting.
+ * seen_p list. Mark anything that can be reached from
+ * uninteresting commits not interesting.
*/
for (;;) {
int changed = 0;
@@ -701,6 +702,8 @@ int cmd_show_branch(int ac, const char **av, char **envp)
if (0 <= extra)
join_revs(&list, &seen, num_rev, extra);
+ sort_by_date(&seen);
+
if (merge_base)
return show_merge_base(seen, num_rev);
diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c
index f2e48aae2a..e5aaded820 100644
--- a/builtin-tar-tree.c
+++ b/builtin-tar-tree.c
@@ -20,6 +20,7 @@ static char block[BLOCKSIZE];
static unsigned long offset;
static time_t archive_time;
+static int tar_umask;
/* tries hard to write, either succeeds or dies in the attempt */
static void reliable_write(const void *data, unsigned long size)
@@ -188,13 +189,13 @@ static void write_entry(const unsigned char *sha1, struct strbuf *path,
} else {
if (S_ISDIR(mode)) {
*header.typeflag = TYPEFLAG_DIR;
- mode |= 0777;
+ mode = (mode | 0777) & ~tar_umask;
} else if (S_ISLNK(mode)) {
*header.typeflag = TYPEFLAG_LNK;
mode |= 0777;
} else if (S_ISREG(mode)) {
*header.typeflag = TYPEFLAG_REG;
- mode |= (mode & 0100) ? 0777 : 0666;
+ mode = (mode | ((mode & 0100) ? 0777 : 0666)) & ~tar_umask;
} else {
error("unsupported file mode: 0%o (SHA1: %s)",
mode, sha1_to_hex(sha1));
@@ -293,6 +294,20 @@ static void traverse_tree(struct tree_desc *tree, struct strbuf *path)
}
}
+int git_tar_config(const char *var, const char *value)
+{
+ if (!strcmp(var, "tar.umask")) {
+ if (!strcmp(value, "user")) {
+ tar_umask = umask(0);
+ umask(tar_umask);
+ } else {
+ tar_umask = git_config_int(var, value);
+ }
+ return 0;
+ }
+ return git_default_config(var, value);
+}
+
static int generate_tar(int argc, const char **argv, char** envp)
{
unsigned char sha1[20], tree_sha1[20];
@@ -305,7 +320,7 @@ static int generate_tar(int argc, const char **argv, char** envp)
current_path.len = current_path.eof = 0;
setup_git_directory();
- git_config(git_default_config);
+ git_config(git_tar_config);
switch (argc) {
case 3:
diff --git a/commit.c b/commit.c
index 6ac3bf7554..77f0ca175c 100644
--- a/commit.c
+++ b/commit.c
@@ -56,7 +56,7 @@ static struct commit *check_commit(struct object *obj,
const unsigned char *sha1,
int quiet)
{
- if (obj->type != TYPE_COMMIT) {
+ if (obj->type != OBJ_COMMIT) {
if (!quiet)
error("Object %s is a %s, not a commit",
sha1_to_hex(sha1), typename(obj->type));
@@ -86,11 +86,11 @@ struct commit *lookup_commit(const unsigned char *sha1)
if (!obj) {
struct commit *ret = alloc_commit_node();
created_object(sha1, &ret->object);
- ret->object.type = TYPE_COMMIT;
+ ret->object.type = OBJ_COMMIT;
return ret;
}
if (!obj->type)
- obj->type = TYPE_COMMIT;
+ obj->type = OBJ_COMMIT;
return check_commit(obj, sha1, 0);
}
diff --git a/contrib/emacs/git.el b/contrib/emacs/git.el
index 34c995046d..68de9be0c7 100644
--- a/contrib/emacs/git.el
+++ b/contrib/emacs/git.el
@@ -55,7 +55,8 @@
;;;; ------------------------------------------------------------
(defgroup git nil
- "Git user interface")
+ "A user interface for the git versioning system."
+ :group 'tools)
(defcustom git-committer-name nil
"User name to use for commits.
@@ -83,6 +84,12 @@ then to `add-log-mailing-address' and then to `user-mail-address'."
:group 'git
:type 'boolean)
+(defcustom git-reuse-status-buffer t
+ "Whether `git-status' should try to reuse an existing buffer
+if there is already one that displays the same directory."
+ :group 'git
+ :type 'boolean)
+
(defcustom git-per-dir-ignore-file ".gitignore"
"Name of the per-directory ignore file."
:group 'git
@@ -258,7 +265,7 @@ and returns the process output as a string."
(set-buffer (find-file-noselect ignore-name))
(goto-char (point-max))
(unless (zerop (current-column)) (insert "\n"))
- (insert name "\n")
+ (insert "/" name "\n")
(sort-lines nil (point-min) (point-max))
(save-buffer))
(when created
@@ -584,6 +591,8 @@ and returns the process output as a string."
(condition-case nil (delete-file ".git/MERGE_HEAD") (error nil))
(with-current-buffer buffer (erase-buffer))
(git-set-files-state files 'uptodate)
+ (when (file-directory-p ".git/rr-cache")
+ (git-run-command nil nil "rerere"))
(git-refresh-files)
(git-refresh-ewoc-hf git-status)
(message "Committed %s." commit))
@@ -1001,12 +1010,28 @@ Commands:
(set (make-local-variable 'list-buffers-directory) default-directory)
(run-hooks 'git-status-mode-hook)))
+(defun git-find-status-buffer (dir)
+ "Find the git status buffer handling a specified directory."
+ (let ((list (buffer-list))
+ (fulldir (expand-file-name dir))
+ found)
+ (while (and list (not found))
+ (let ((buffer (car list)))
+ (with-current-buffer buffer
+ (when (and list-buffers-directory
+ (string-equal fulldir (expand-file-name list-buffers-directory))
+ (string-match "\\*git-status\\*$" (buffer-name buffer)))
+ (setq found buffer))))
+ (setq list (cdr list)))
+ found))
+
(defun git-status (dir)
"Entry point into git-status mode."
(interactive "DSelect directory: ")
(setq dir (git-get-top-dir dir))
(if (file-directory-p (concat (file-name-as-directory dir) ".git"))
- (let ((buffer (create-file-buffer (expand-file-name "*git-status*" dir))))
+ (let ((buffer (or (and git-reuse-status-buffer (git-find-status-buffer dir))
+ (create-file-buffer (expand-file-name "*git-status*" dir)))))
(switch-to-buffer buffer)
(cd dir)
(git-status-mode)
diff --git a/describe.c b/describe.c
index 8e68d5df33..324ca8965b 100644
--- a/describe.c
+++ b/describe.c
@@ -67,7 +67,7 @@ static int get_name(const char *path, const unsigned char *sha1)
* Otherwise only annotated tags are used.
*/
if (!strncmp(path, "refs/tags/", 10)) {
- if (object->type == TYPE_TAG)
+ if (object->type == OBJ_TAG)
prio = 2;
else
prio = 1;
diff --git a/diff.c b/diff.c
index 8b44756136..6a71376483 100644
--- a/diff.c
+++ b/diff.c
@@ -17,15 +17,6 @@ static int diff_detect_rename_default = 0;
static int diff_rename_limit_default = -1;
static int diff_use_color_default = 0;
-enum color_diff {
- DIFF_RESET = 0,
- DIFF_PLAIN = 1,
- DIFF_METAINFO = 2,
- DIFF_FRAGINFO = 3,
- DIFF_FILE_OLD = 4,
- DIFF_FILE_NEW = 5,
-};
-
/* "\033[1;38;5;2xx;48;5;2xxm\0" is 23 bytes */
static char diff_colors[][24] = {
"\033[m", /* reset */
@@ -33,7 +24,8 @@ static char diff_colors[][24] = {
"\033[1m", /* bold */
"\033[36m", /* cyan */
"\033[31m", /* red */
- "\033[32m" /* green */
+ "\033[32m", /* green */
+ "\033[33m" /* yellow */
};
static int parse_diff_color_slot(const char *var, int ofs)
@@ -48,6 +40,8 @@ static int parse_diff_color_slot(const char *var, int ofs)
return DIFF_FILE_OLD;
if (!strcasecmp(var+ofs, "new"))
return DIFF_FILE_NEW;
+ if (!strcasecmp(var+ofs, "commit"))
+ return DIFF_COMMIT;
die("bad config variable '%s'", var);
}
@@ -370,7 +364,7 @@ struct emit_callback {
const char **label_path;
};
-static inline const char *get_color(int diff_use_color, enum color_diff ix)
+const char *diff_get_color(int diff_use_color, enum color_diff ix)
{
if (diff_use_color)
return diff_colors[ix];
@@ -381,8 +375,8 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
{
int i;
struct emit_callback *ecbdata = priv;
- const char *set = get_color(ecbdata->color_diff, DIFF_METAINFO);
- const char *reset = get_color(ecbdata->color_diff, DIFF_RESET);
+ const char *set = diff_get_color(ecbdata->color_diff, DIFF_METAINFO);
+ const char *reset = diff_get_color(ecbdata->color_diff, DIFF_RESET);
if (ecbdata->label_path[0]) {
printf("%s--- %s%s\n", set, ecbdata->label_path[0], reset);
@@ -397,7 +391,7 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
;
if (2 <= i && i < len && line[i] == ' ') {
ecbdata->nparents = i - 1;
- set = get_color(ecbdata->color_diff, DIFF_FRAGINFO);
+ set = diff_get_color(ecbdata->color_diff, DIFF_FRAGINFO);
}
else if (len < ecbdata->nparents)
set = reset;
@@ -410,7 +404,7 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
else if (line[i] == '+')
color = DIFF_FILE_NEW;
}
- set = get_color(ecbdata->color_diff, color);
+ set = diff_get_color(ecbdata->color_diff, color);
}
if (len > 0 && line[len-1] == '\n')
len--;
@@ -767,8 +761,8 @@ static void builtin_diff(const char *name_a,
mmfile_t mf1, mf2;
const char *lbl[2];
char *a_one, *b_two;
- const char *set = get_color(o->color_diff, DIFF_METAINFO);
- const char *reset = get_color(o->color_diff, DIFF_RESET);
+ const char *set = diff_get_color(o->color_diff, DIFF_METAINFO);
+ const char *reset = diff_get_color(o->color_diff, DIFF_RESET);
a_one = quote_two("a/", name_a);
b_two = quote_two("b/", name_b);
diff --git a/diff.h b/diff.h
index a06f959938..2cced530fa 100644
--- a/diff.h
+++ b/diff.h
@@ -69,6 +69,17 @@ struct diff_options {
add_remove_fn_t add_remove;
};
+enum color_diff {
+ DIFF_RESET = 0,
+ DIFF_PLAIN = 1,
+ DIFF_METAINFO = 2,
+ DIFF_FRAGINFO = 3,
+ DIFF_FILE_OLD = 4,
+ DIFF_FILE_NEW = 5,
+ DIFF_COMMIT = 6,
+};
+const char *diff_get_color(int diff_use_color, enum color_diff ix);
+
extern const char mime_boundary_leader[];
extern void diff_tree_setup_paths(const char **paths, struct diff_options *);
diff --git a/fetch-pack.c b/fetch-pack.c
index f2c51ebe4b..b7824dbed4 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -46,7 +46,7 @@ static int rev_list_insert_ref(const char *path, const unsigned char *sha1)
{
struct object *o = deref_tag(parse_object(sha1), path, 0);
- if (o && o->type == TYPE_COMMIT)
+ if (o && o->type == OBJ_COMMIT)
rev_list_push((struct commit *)o, SEEN);
return 0;
@@ -256,14 +256,14 @@ static int mark_complete(const char *path, const unsigned char *sha1)
{
struct object *o = parse_object(sha1);
- while (o && o->type == TYPE_TAG) {
+ while (o && o->type == OBJ_TAG) {
struct tag *t = (struct tag *) o;
if (!t->tagged)
break; /* broken repository */
o->flags |= COMPLETE;
o = parse_object(t->tagged->sha1);
}
- if (o && o->type == TYPE_COMMIT) {
+ if (o && o->type == OBJ_COMMIT) {
struct commit *commit = (struct commit *)o;
commit->object.flags |= COMPLETE;
insert_by_date(commit, &complete);
@@ -357,7 +357,7 @@ static int everything_local(struct ref **refs, int nr_match, char **match)
* in sync with the other side at some time after
* that (it is OK if we guess wrong here).
*/
- if (o->type == TYPE_COMMIT) {
+ if (o->type == OBJ_COMMIT) {
struct commit *commit = (struct commit *)o;
if (!cutoff || cutoff < commit->date)
cutoff = commit->date;
@@ -376,7 +376,7 @@ static int everything_local(struct ref **refs, int nr_match, char **match)
struct object *o = deref_tag(lookup_object(ref->old_sha1),
NULL, 0);
- if (!o || o->type != TYPE_COMMIT || !(o->flags & COMPLETE))
+ if (!o || o->type != OBJ_COMMIT || !(o->flags & COMPLETE))
continue;
if (!(o->flags & SEEN)) {
diff --git a/fetch.c b/fetch.c
index 238032b798..989d7a4788 100644
--- a/fetch.c
+++ b/fetch.c
@@ -118,20 +118,20 @@ static struct object_list **process_queue_end = &process_queue;
static int process_object(struct object *obj)
{
- if (obj->type == TYPE_COMMIT) {
+ if (obj->type == OBJ_COMMIT) {
if (process_commit((struct commit *)obj))
return -1;
return 0;
}
- if (obj->type == TYPE_TREE) {
+ if (obj->type == OBJ_TREE) {
if (process_tree((struct tree *)obj))
return -1;
return 0;
}
- if (obj->type == TYPE_BLOB) {
+ if (obj->type == OBJ_BLOB) {
return 0;
}
- if (obj->type == TYPE_TAG) {
+ if (obj->type == OBJ_TAG) {
if (process_tag((struct tag *)obj))
return -1;
return 0;
diff --git a/fsck-objects.c b/fsck-objects.c
index ef54a8a411..e167f4105f 100644
--- a/fsck-objects.c
+++ b/fsck-objects.c
@@ -297,13 +297,13 @@ static int fsck_sha1(unsigned char *sha1)
if (obj->flags & SEEN)
return 0;
obj->flags |= SEEN;
- if (obj->type == TYPE_BLOB)
+ if (obj->type == OBJ_BLOB)
return 0;
- if (obj->type == TYPE_TREE)
+ if (obj->type == OBJ_TREE)
return fsck_tree((struct tree *) obj);
- if (obj->type == TYPE_COMMIT)
+ if (obj->type == OBJ_COMMIT)
return fsck_commit((struct commit *) obj);
- if (obj->type == TYPE_TAG)
+ if (obj->type == OBJ_TAG)
return fsck_tag((struct tag *) obj);
/* By now, parse_object() would've returned NULL instead. */
return objerror(obj, "unknown type '%d' (internal fsck error)", obj->type);
@@ -472,7 +472,7 @@ static int fsck_cache_tree(struct cache_tree *it)
}
mark_reachable(obj, REACHABLE);
obj->used = 1;
- if (obj->type != TYPE_TREE)
+ if (obj->type != OBJ_TREE)
err |= objerror(obj, "non-tree in cache-tree");
}
for (i = 0; i < it->subtree_nr; i++)
diff --git a/git-am.sh b/git-am.sh
index db9a20a811..04f0119435 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -91,6 +91,7 @@ fall_back_3way () {
}
prec=4
+rloga=am
dotest=.dotest sign= utf8= keep= skip= interactive= resolved= binary= ws= resolvemsg=
while case "$#" in 0) break;; esac
@@ -130,6 +131,9 @@ do
--resolvemsg=*)
resolvemsg=$(echo "$1" | sed -e "s/^--resolvemsg=//"); shift ;;
+ --reflog-action=*)
+ rloga=`expr "z$1" : 'z-[^=]*=\(.*\)'`; shift ;;
+
--)
shift; break ;;
-*)
@@ -152,8 +156,10 @@ fi
if test -d "$dotest"
then
- test ",$#," = ",0," ||
- die "previous dotest directory $dotest still exists but mbox given."
+ if test ",$#," != ",0," || ! tty -s
+ then
+ die "previous dotest directory $dotest still exists but mbox given."
+ fi
resume=yes
else
# Make sure we are not given --skip nor --resolved
@@ -413,7 +419,7 @@ do
parent=$(git-rev-parse --verify HEAD) &&
commit=$(git-commit-tree $tree -p $parent <"$dotest/final-commit") &&
echo Committed: $commit &&
- git-update-ref -m "am: $SUBJECT" HEAD $commit $parent ||
+ git-update-ref -m "$rloga: $SUBJECT" HEAD $commit $parent ||
stop_here $this
if test -x "$GIT_DIR"/hooks/post-applypatch
diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl
index 5d13a54194..99b3dc392a 100755
--- a/git-cvsexportcommit.perl
+++ b/git-cvsexportcommit.perl
@@ -16,9 +16,9 @@ unless ($ENV{GIT_DIR} && -r $ENV{GIT_DIR}){
die "GIT_DIR is not defined or is unreadable";
}
-our ($opt_h, $opt_p, $opt_v, $opt_c, $opt_f, $opt_m );
+our ($opt_h, $opt_p, $opt_v, $opt_c, $opt_f, $opt_a, $opt_m );
-getopts('hpvcfm:');
+getopts('hpvcfam:');
$opt_h && usage();
@@ -29,7 +29,6 @@ our ($tmpdir, $tmpdirname) = tempdir('git-cvsapplycommit-XXXXXX',
TMPDIR => 1,
CLEANUP => 1);
-print Dumper(@ARGV);
# resolve target commit
my $commit;
$commit = pop @ARGV;
@@ -53,12 +52,32 @@ if (@ARGV) {
# find parents from the commit itself
my @commit = safe_pipe_capture('git-cat-file', 'commit', $commit);
my @parents;
-foreach my $p (@commit) {
- if ($p =~ m/^$/) { # end of commit headers, we're done
- last;
+my $committer;
+my $author;
+my $stage = 'headers'; # headers, msg
+my $title;
+my $msg = '';
+
+foreach my $line (@commit) {
+ chomp $line;
+ if ($stage eq 'headers' && $line eq '') {
+ $stage = 'msg';
+ next;
}
- if ($p =~ m/^parent (\w{40})$/) { # found a parent
- push @parents, $1;
+
+ if ($stage eq 'headers') {
+ if ($line =~ m/^parent (\w{40})$/) { # found a parent
+ push @parents, $1;
+ } elsif ($line =~ m/^author (.+) \d+ \+\d+$/) {
+ $author = $1;
+ } elsif ($line =~ m/^committer (.+) \d+ \+\d+$/) {
+ $committer = $1;
+ }
+ } else {
+ $msg .= $line . "\n";
+ unless ($title) {
+ $title = $line;
+ }
}
}
@@ -84,12 +103,18 @@ $opt_v && print "Applying to CVS commit $commit from parent $parent\n";
# grab the commit message
open(MSG, ">.msg") or die "Cannot open .msg for writing";
-print MSG $opt_m;
+if ($opt_m) {
+ print MSG $opt_m;
+}
+print MSG $msg;
+if ($opt_a) {
+ print MSG "\n\nAuthor: $author\n";
+ if ($author ne $committer) {
+ print MSG "Committer: $committer\n";
+ }
+}
close MSG;
-`git-cat-file commit $commit | sed -e '1,/^\$/d' >> .msg`;
-$? && die "Error extracting the commit message";
-
my (@afiles, @dfiles, @mfiles, @dirs);
my @files = safe_pipe_capture('git-diff-tree', '-r', $parent, $commit);
#print @files;
@@ -233,6 +258,7 @@ foreach my $f (@dfiles) {
}
print "Commit to CVS\n";
+print "Patch: $title\n";
my $commitfiles = join(' ', @afiles, @mfiles, @dfiles);
my $cmd = "cvs commit -F .msg $commitfiles";
diff --git a/git-fetch.sh b/git-fetch.sh
index ff1769952b..f7167abdf0 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -20,6 +20,7 @@ verbose=
update_head_ok=
exec=
upload_pack=
+keep=--thin
while case "$#" in 0) break ;; esac
do
case "$1" in
@@ -69,7 +70,8 @@ case "$#" in
0)
test -f "$GIT_DIR/branches/origin" ||
test -f "$GIT_DIR/remotes/origin" ||
- die "Where do you want to fetch from today?"
+ git-repo-config --get remote.origin.url >/dev/null ||
+ die "Where do you want to fetch from today?"
set origin ;;
esac
@@ -153,7 +155,7 @@ fast_forward_local () {
then
if now_=$(cat "$GIT_DIR/$1") && test "$now_" = "$2"
then
- [ "$verbose" ] && echo >&2 "* $1: same as $3"
+ [ "$verbose" ] && echo >&2 "* $1: same as $3" ||:
else
echo >&2 "* $1: updating with $3"
git-update-ref -m "$rloga: updating tag" "$1" "$2"
@@ -347,7 +349,7 @@ fetch_main () {
( : subshell because we muck with IFS
IFS=" $LF"
(
- git-fetch-pack $exec $keep --thin "$remote" $rref || echo failed "$remote"
+ git-fetch-pack $exec $keep "$remote" $rref || echo failed "$remote"
) |
while read sha1 remote_name
do
diff --git a/git-merge.sh b/git-merge.sh
index 24e3b507ef..a9cfafb1df 100755
--- a/git-merge.sh
+++ b/git-merge.sh
@@ -58,7 +58,13 @@ squash_message () {
}
finish () {
- test '' = "$2" || echo "$2"
+ if test '' = "$2"
+ then
+ rlogm="$rloga"
+ else
+ echo "$2"
+ rlogm="$rloga: $2"
+ fi
case "$squash" in
t)
echo "Squash commit -- not updating HEAD"
@@ -70,7 +76,7 @@ finish () {
echo "No merge message -- not updating HEAD"
;;
*)
- git-update-ref HEAD "$1" "$head" || exit 1
+ git-update-ref -m "$rlogm" HEAD "$1" "$head" || exit 1
;;
esac
;;
@@ -88,6 +94,7 @@ finish () {
esac
}
+rloga=
while case "$#" in 0) break ;; esac
do
case "$1" in
@@ -117,6 +124,9 @@ do
die "available strategies are: $all_strategies" ;;
esac
;;
+ --reflog-action=*)
+ rloga=`expr "z$1" : 'z-[^=]*=\(.*\)'`
+ ;;
-*) usage ;;
*) break ;;
esac
@@ -131,6 +141,7 @@ shift
# All the rest are remote heads
test "$#" = 0 && usage ;# we need at least one remote head.
+test "$rloga" = '' && rloga="merge: $@"
remoteheads=
for remote
@@ -316,7 +327,7 @@ if test '' != "$result_tree"
then
parents=$(git-show-branch --independent "$head" "$@" | sed -e 's/^/-p /')
result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree $parents) || exit
- finish "$result_commit" "Merge $result_commit, made by $wt_strategy."
+ finish "$result_commit" "Merge made by $wt_strategy."
dropsave
exit 0
fi
diff --git a/git-pull.sh b/git-pull.sh
index d337bf4da3..f380437997 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -102,5 +102,6 @@ case "$strategy_args" in
esac
merge_name=$(git-fmt-merge-msg <"$GIT_DIR/FETCH_HEAD") || exit
-git-merge $no_summary $no_commit $squash $strategy_args \
+git-merge "--reflog-action=pull $*" \
+ $no_summary $no_commit $squash $strategy_args \
"$merge_name" HEAD $merge_head
diff --git a/git-quiltimport.sh b/git-quiltimport.sh
index 364baff806..10135da3ac 100755
--- a/git-quiltimport.sh
+++ b/git-quiltimport.sh
@@ -112,7 +112,7 @@ for patch_name in $(cat "$QUILT_PATCHES/series" | grep -v '^#'); do
git-apply --index -C1 "$tmp_patch" &&
tree=$(git-write-tree) &&
commit=$((echo "$SUBJECT"; echo; cat "$tmp_msg") | git-commit-tree $tree -p $commit) &&
- git-update-ref HEAD $commit || exit 4
+ git-update-ref -m "quiltimport: $patch_name" HEAD $commit || exit 4
fi
done
rm -rf $tmp_dir || exit 5
diff --git a/git-rebase.sh b/git-rebase.sh
index 1b9e986926..29028dd5fc 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -131,7 +131,8 @@ do
finish_rb_merge
exit
fi
- git am --resolved --3way --resolvemsg="$RESOLVEMSG"
+ git am --resolved --3way --resolvemsg="$RESOLVEMSG" \
+ --reflog-action=rebase
exit
;;
--skip)
@@ -150,7 +151,8 @@ do
finish_rb_merge
exit
fi
- git am -3 --skip --resolvemsg="$RESOLVEMSG"
+ git am -3 --skip --resolvemsg="$RESOLVEMSG" \
+ --reflog-action=rebase
exit
;;
--abort)
@@ -288,7 +290,8 @@ fi
if test -z "$do_merge"
then
git-format-patch -k --stdout --full-index "$upstream"..ORIG_HEAD |
- git am --binary -3 -k --resolvemsg="$RESOLVEMSG"
+ git am --binary -3 -k --resolvemsg="$RESOLVEMSG" \
+ --reflog-action=rebase
exit $?
fi
diff --git a/git-resolve.sh b/git-resolve.sh
index 1c7aaefa25..a7bc680d90 100755
--- a/git-resolve.sh
+++ b/git-resolve.sh
@@ -15,6 +15,7 @@ dropheads() {
head=$(git-rev-parse --verify "$1"^0) &&
merge=$(git-rev-parse --verify "$2"^0) &&
+merge_name="$2" &&
merge_msg="$3" || usage
#
@@ -43,7 +44,8 @@ case "$common" in
"$head")
echo "Updating from $head to $merge"
git-read-tree -u -m $head $merge || exit 1
- git-update-ref HEAD "$merge" "$head"
+ git-update-ref -m "resolve $merge_name: Fast forward" \
+ HEAD "$merge" "$head"
git-diff-tree -p $head $merge | git-apply --stat
dropheads
exit 0
@@ -100,6 +102,7 @@ if [ $? -ne 0 ]; then
fi
result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree -p $head -p $merge)
echo "Committed merge $result_commit"
-git-update-ref HEAD "$result_commit" "$head"
+git-update-ref -m "resolve $merge_name: In-index merge" \
+ HEAD "$result_commit" "$head"
git-diff-tree -p $head $result_commit | git-apply --stat
dropheads
diff --git a/git-svn.perl b/git-svn.perl
index 4530ffe42c..6453771f9c 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -147,7 +147,7 @@ init_vars();
load_authors() if $_authors;
load_all_refs() if $_branch_all_refs;
svn_compat_check() unless $_use_lib;
-migration_check() unless $cmd =~ /^(?:init|rebuild|multi-init)$/;
+migration_check() unless $cmd =~ /^(?:init|rebuild|multi-init|commit-diff)$/;
$cmd{$cmd}->[0]->(@ARGV);
exit 0;
@@ -2709,6 +2709,12 @@ sub libsvn_fetch {
} else {
die "Unrecognized action: $m, ($f r$rev)\n";
}
+ } elsif ($t == $SVN::Node::dir && $m =~ /^[AR]$/) {
+ my @traversed = ();
+ libsvn_traverse($gui, '', $f, $rev, \@traversed);
+ foreach (@traversed) {
+ push @amr, [ $m, $_ ]
+ }
}
$pool->clear;
}
@@ -2778,7 +2784,7 @@ sub libsvn_parse_revision {
}
sub libsvn_traverse {
- my ($gui, $pfx, $path, $rev) = @_;
+ my ($gui, $pfx, $path, $rev, $files) = @_;
my $cwd = "$pfx/$path";
my $pool = SVN::Pool->new;
$cwd =~ s#^/+##g;
@@ -2786,10 +2792,15 @@ sub libsvn_traverse {
foreach my $d (keys %$dirent) {
my $t = $dirent->{$d}->kind;
if ($t == $SVN::Node::dir) {
- libsvn_traverse($gui, $cwd, $d, $rev);
+ libsvn_traverse($gui, $cwd, $d, $rev, $files);
} elsif ($t == $SVN::Node::file) {
- print "\tA\t$cwd/$d\n" unless $_q;
- libsvn_get_file($gui, "$cwd/$d", $rev);
+ my $file = "$cwd/$d";
+ if (defined $files) {
+ push @$files, $file;
+ } else {
+ print "\tA\t$file\n" unless $_q;
+ libsvn_get_file($gui, $file, $rev);
+ }
}
}
$pool->clear;
@@ -2913,9 +2924,7 @@ sub libsvn_new_tree {
}
my ($paths, $rev, $author, $date, $msg) = @_;
open my $gui, '| git-update-index -z --index-info' or croak $!;
- my $pool = SVN::Pool->new;
- libsvn_traverse($gui, '', $SVN_PATH, $rev, $pool);
- $pool->clear;
+ libsvn_traverse($gui, '', $SVN_PATH, $rev);
close $gui or croak $?;
return libsvn_log_entry($rev, $author, $date, $msg);
}
diff --git a/git.c b/git.c
index 102735af6c..ee5a0e86a7 100644
--- a/git.c
+++ b/git.c
@@ -133,13 +133,12 @@ static int handle_alias(int *argcp, const char ***argv)
fflush(stderr);
}
+ new_argv = realloc(new_argv, sizeof(char*) *
+ (count + *argcp + 1));
/* insert after command name */
- if (*argcp > 1) {
- new_argv = realloc(new_argv, sizeof(char*) *
- (count + *argcp));
- memcpy(new_argv + count, *argv + 1,
- sizeof(char*) * *argcp);
- }
+ memcpy(new_argv + count, *argv + 1,
+ sizeof(char*) * *argcp);
+ new_argv[count+*argcp] = NULL;
*argv = new_argv;
*argcp += count - 1;
diff --git a/http-push.c b/http-push.c
index f761584d7e..47686195cd 100644
--- a/http-push.c
+++ b/http-push.c
@@ -1784,16 +1784,16 @@ static int get_delta(struct rev_info *revs, struct remote_lock *lock)
if (obj->flags & (UNINTERESTING | SEEN))
continue;
- if (obj->type == TYPE_TAG) {
+ if (obj->type == OBJ_TAG) {
obj->flags |= SEEN;
p = add_one_object(obj, p);
continue;
}
- if (obj->type == TYPE_TREE) {
+ if (obj->type == OBJ_TREE) {
p = process_tree((struct tree *)obj, p, NULL, name);
continue;
}
- if (obj->type == TYPE_BLOB) {
+ if (obj->type == OBJ_BLOB) {
p = process_blob((struct blob *)obj, p, NULL, name);
continue;
}
@@ -1960,12 +1960,12 @@ static int ref_newer(const unsigned char *new_sha1,
* old. Otherwise we require --force.
*/
o = deref_tag(parse_object(old_sha1), NULL, 0);
- if (!o || o->type != TYPE_COMMIT)
+ if (!o || o->type != OBJ_COMMIT)
return 0;
old = (struct commit *) o;
o = deref_tag(parse_object(new_sha1), NULL, 0);
- if (!o || o->type != TYPE_COMMIT)
+ if (!o || o->type != OBJ_COMMIT)
return 0;
new = (struct commit *) o;
@@ -2044,7 +2044,7 @@ static void add_remote_info_ref(struct remote_ls_ctx *ls)
fwrite_buffer(ref_info, 1, len, buf);
free(ref_info);
- if (o->type == TYPE_TAG) {
+ if (o->type == OBJ_TAG) {
o = deref_tag(o, ls->dentry_name, 0);
if (o) {
len = strlen(ls->dentry_name) + 45;
diff --git a/log-tree.c b/log-tree.c
index 9d8d46fa00..3a6c84dab5 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -129,7 +129,8 @@ void show_log(struct rev_info *opt, const char *sep)
opt->diffopt.stat_sep = buffer;
}
} else {
- printf("%s%s",
+ printf("%s%s%s",
+ diff_get_color(opt->diffopt.color_diff, DIFF_COMMIT),
opt->commit_format == CMIT_FMT_ONELINE ? "" : "commit ",
diff_unique_abbrev(commit->object.sha1, abbrev_commit));
if (opt->parents)
@@ -138,6 +139,8 @@ void show_log(struct rev_info *opt, const char *sep)
printf(" (from %s)",
diff_unique_abbrev(parent->object.sha1,
abbrev_commit));
+ printf("%s",
+ diff_get_color(opt->diffopt.color_diff, DIFF_RESET));
putchar(opt->commit_format == CMIT_FMT_ONELINE ? ' ' : '\n');
}
diff --git a/name-rev.c b/name-rev.c
index 083d067e17..f92f14e32f 100644
--- a/name-rev.c
+++ b/name-rev.c
@@ -84,14 +84,14 @@ static int name_ref(const char *path, const unsigned char *sha1)
if (tags_only && strncmp(path, "refs/tags/", 10))
return 0;
- while (o && o->type == TYPE_TAG) {
+ while (o && o->type == OBJ_TAG) {
struct tag *t = (struct tag *) o;
if (!t->tagged)
break; /* broken repository */
o = parse_object(t->tagged->sha1);
deref = 1;
}
- if (o && o->type == TYPE_COMMIT) {
+ if (o && o->type == OBJ_COMMIT) {
struct commit *commit = (struct commit *)o;
if (!strncmp(path, "refs/heads/", 11))
@@ -111,7 +111,7 @@ static const char* get_rev_name(struct object *o)
struct rev_name *n;
struct commit *c;
- if (o->type != TYPE_COMMIT)
+ if (o->type != OBJ_COMMIT)
return "undefined";
c = (struct commit *) o;
n = c->util;
@@ -172,7 +172,7 @@ int main(int argc, char **argv)
}
o = deref_tag(parse_object(sha1), *argv, 0);
- if (!o || o->type != TYPE_COMMIT) {
+ if (!o || o->type != OBJ_COMMIT) {
fprintf(stderr, "Could not get commit for %s. Skipping.\n",
*argv);
continue;
diff --git a/object.c b/object.c
index 37277f9438..b5d8ed467d 100644
--- a/object.c
+++ b/object.c
@@ -19,7 +19,8 @@ struct object *get_indexed_object(unsigned int idx)
}
const char *type_names[] = {
- "none", "blob", "tree", "commit", "bad"
+ "none", "commit", "tree", "blob", "tag",
+ "bad type 5", "bad type 6", "delta", "bad",
};
static unsigned int hash_obj(struct object *obj, unsigned int n)
@@ -88,7 +89,7 @@ void created_object(const unsigned char *sha1, struct object *obj)
{
obj->parsed = 0;
obj->used = 0;
- obj->type = TYPE_NONE;
+ obj->type = OBJ_NONE;
obj->flags = 0;
memcpy(obj->sha1, sha1, 20);
@@ -131,7 +132,7 @@ struct object *lookup_unknown_object(const unsigned char *sha1)
if (!obj) {
union any_object *ret = xcalloc(1, sizeof(*ret));
created_object(sha1, &ret->object);
- ret->object.type = TYPE_NONE;
+ ret->object.type = OBJ_NONE;
return &ret->object;
}
return obj;
diff --git a/object.h b/object.h
index e0125e154f..733faac4cc 100644
--- a/object.h
+++ b/object.h
@@ -24,12 +24,19 @@ struct object_array {
#define TYPE_BITS 3
#define FLAG_BITS 27
-#define TYPE_NONE 0
-#define TYPE_BLOB 1
-#define TYPE_TREE 2
-#define TYPE_COMMIT 3
-#define TYPE_TAG 4
-#define TYPE_BAD 5
+/*
+ * The object type is stored in 3 bits.
+ */
+enum object_type {
+ OBJ_NONE = 0,
+ OBJ_COMMIT = 1,
+ OBJ_TREE = 2,
+ OBJ_BLOB = 3,
+ OBJ_TAG = 4,
+ /* 5/6 for future expansion */
+ OBJ_DELTA = 7,
+ OBJ_BAD,
+};
struct object {
unsigned parsed : 1;
@@ -40,14 +47,14 @@ struct object {
};
extern int track_object_refs;
-extern const char *type_names[];
+extern const char *type_names[9];
extern unsigned int get_max_object_index(void);
extern struct object *get_indexed_object(unsigned int);
static inline const char *typename(unsigned int type)
{
- return type_names[type > TYPE_TAG ? TYPE_BAD : type];
+ return type_names[type > OBJ_BAD ? OBJ_BAD : type];
}
extern struct object_refs *lookup_object_refs(struct object *);
diff --git a/pack-objects.c b/pack-objects.c
index 04a48b925b..861c7f08ff 100644
--- a/pack-objects.c
+++ b/pack-objects.c
@@ -63,6 +63,7 @@ static const char *base_name;
static unsigned char pack_file_sha1[20];
static int progress = 1;
static volatile sig_atomic_t progress_update = 0;
+static int window = 10;
/*
* The object names in objects array are hashed with this hashtable,
@@ -1216,16 +1217,26 @@ static void setup_progress_signal(void)
setitimer(ITIMER_REAL, &v, NULL);
}
+static int git_pack_config(const char *k, const char *v)
+{
+ if(!strcmp(k, "pack.window")) {
+ window = git_config_int(k, v);
+ return 0;
+ }
+ return git_default_config(k, v);
+}
+
int main(int argc, char **argv)
{
SHA_CTX ctx;
char line[40 + 1 + PATH_MAX + 2];
- int window = 10, depth = 10, pack_to_stdout = 0;
+ int depth = 10, pack_to_stdout = 0;
struct object_entry **list;
int num_preferred_base = 0;
int i;
setup_git_directory();
+ git_config(git_pack_config);
progress = isatty(2);
for (i = 1; i < argc; i++) {
diff --git a/pack.h b/pack.h
index 694e0c56f0..eb07b033ae 100644
--- a/pack.h
+++ b/pack.h
@@ -1,20 +1,7 @@
#ifndef PACK_H
#define PACK_H
-/*
- * The packed object type is stored in 3 bits.
- * The type value 0 is a reserved prefix if ever there is more than 7
- * object types, or any future format extensions.
- */
-enum object_type {
- OBJ_EXT = 0,
- OBJ_COMMIT = 1,
- OBJ_TREE = 2,
- OBJ_BLOB = 3,
- OBJ_TAG = 4,
- /* 5/6 for future expansion */
- OBJ_DELTA = 7,
-};
+#include "object.h"
/*
* Packed object header
diff --git a/revision.c b/revision.c
index 7df9089f53..874e349db8 100644
--- a/revision.c
+++ b/revision.c
@@ -135,7 +135,7 @@ static struct commit *handle_commit(struct rev_info *revs, struct object *object
/*
* Tag object? Look what it points to..
*/
- while (object->type == TYPE_TAG) {
+ while (object->type == OBJ_TAG) {
struct tag *tag = (struct tag *) object;
if (revs->tag_objects && !(flags & UNINTERESTING))
add_pending_object(revs, object, tag->tag);
@@ -148,7 +148,7 @@ static struct commit *handle_commit(struct rev_info *revs, struct object *object
* Commit object? Just return it, we'll do all the complex
* reachability crud.
*/
- if (object->type == TYPE_COMMIT) {
+ if (object->type == OBJ_COMMIT) {
struct commit *commit = (struct commit *)object;
if (parse_commit(commit) < 0)
die("unable to parse commit %s", name);
@@ -164,7 +164,7 @@ static struct commit *handle_commit(struct rev_info *revs, struct object *object
* Tree object? Either mark it uniniteresting, or add it
* to the list of objects to look at later..
*/
- if (object->type == TYPE_TREE) {
+ if (object->type == OBJ_TREE) {
struct tree *tree = (struct tree *)object;
if (!revs->tree_objects)
return NULL;
@@ -179,7 +179,7 @@ static struct commit *handle_commit(struct rev_info *revs, struct object *object
/*
* Blob object? You know the drill by now..
*/
- if (object->type == TYPE_BLOB) {
+ if (object->type == OBJ_BLOB) {
struct blob *blob = (struct blob *)object;
if (!revs->blob_objects)
return NULL;
@@ -494,11 +494,11 @@ static int add_parents_only(struct rev_info *revs, const char *arg, int flags)
return 0;
while (1) {
it = get_reference(revs, arg, sha1, 0);
- if (it->type != TYPE_TAG)
+ if (it->type != OBJ_TAG)
break;
memcpy(sha1, ((struct tag*)it)->tagged->sha1, 20);
}
- if (it->type != TYPE_COMMIT)
+ if (it->type != OBJ_COMMIT)
return 0;
commit = (struct commit *)it;
for (parents = commit->parents; parents; parents = parents->next) {
diff --git a/send-pack.c b/send-pack.c
index 4019a4b981..10bc8bc359 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -151,12 +151,12 @@ static int ref_newer(const unsigned char *new_sha1,
* old. Otherwise we require --force.
*/
o = deref_tag(parse_object(old_sha1), NULL, 0);
- if (!o || o->type != TYPE_COMMIT)
+ if (!o || o->type != OBJ_COMMIT)
return 0;
old = (struct commit *) o;
o = deref_tag(parse_object(new_sha1), NULL, 0);
- if (!o || o->type != TYPE_COMMIT)
+ if (!o || o->type != OBJ_COMMIT)
return 0;
new = (struct commit *) o;
diff --git a/server-info.c b/server-info.c
index fdfe05a2da..7df628f2b2 100644
--- a/server-info.c
+++ b/server-info.c
@@ -12,7 +12,7 @@ static int add_info_ref(const char *path, const unsigned char *sha1)
struct object *o = parse_object(sha1);
fprintf(info_ref_fp, "%s %s\n", sha1_to_hex(sha1), path);
- if (o->type == TYPE_TAG) {
+ if (o->type == OBJ_TAG) {
o = deref_tag(o, path, 0);
if (o)
fprintf(info_ref_fp, "%s %s^{}\n",
diff --git a/sha1_file.c b/sha1_file.c
index 88a2579412..43bc2ea0cf 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1379,31 +1379,29 @@ char *write_sha1_file_prepare(void *buf,
static int link_temp_to_file(const char *tmpfile, char *filename)
{
int ret;
+ char *dir;
if (!link(tmpfile, filename))
return 0;
/*
- * Try to mkdir the last path component if that failed
- * with an ENOENT.
+ * Try to mkdir the last path component if that failed.
*
* Re-try the "link()" regardless of whether the mkdir
* succeeds, since a race might mean that somebody
* else succeeded.
*/
ret = errno;
- if (ret == ENOENT) {
- char *dir = strrchr(filename, '/');
- if (dir) {
- *dir = 0;
- mkdir(filename, 0777);
- if (adjust_shared_perm(filename))
- return -2;
- *dir = '/';
- if (!link(tmpfile, filename))
- return 0;
- ret = errno;
- }
+ dir = strrchr(filename, '/');
+ if (dir) {
+ *dir = 0;
+ mkdir(filename, 0777);
+ if (adjust_shared_perm(filename))
+ return -2;
+ *dir = '/';
+ if (!link(tmpfile, filename))
+ return 0;
+ ret = errno;
}
return ret;
}
diff --git a/sha1_name.c b/sha1_name.c
index f2cbafa496..5fe8e5d4bf 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -381,13 +381,13 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
sp++; /* beginning of type name, or closing brace for empty */
if (!strncmp(commit_type, sp, 6) && sp[6] == '}')
- expected_type = TYPE_COMMIT;
+ expected_type = OBJ_COMMIT;
else if (!strncmp(tree_type, sp, 4) && sp[4] == '}')
- expected_type = TYPE_TREE;
+ expected_type = OBJ_TREE;
else if (!strncmp(blob_type, sp, 4) && sp[4] == '}')
- expected_type = TYPE_BLOB;
+ expected_type = OBJ_BLOB;
else if (sp[0] == '}')
- expected_type = TYPE_NONE;
+ expected_type = OBJ_NONE;
else
return -1;
@@ -416,9 +416,9 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
memcpy(sha1, o->sha1, 20);
return 0;
}
- if (o->type == TYPE_TAG)
+ if (o->type == OBJ_TAG)
o = ((struct tag*) o)->tagged;
- else if (o->type == TYPE_COMMIT)
+ else if (o->type == OBJ_COMMIT)
o = &(((struct commit *) o)->tree->object);
else
return error("%.*s: expected %s type, but the object dereferences to %s type",
diff --git a/t/t6004-rev-list-path-optim.sh b/t/t6004-rev-list-path-optim.sh
new file mode 100755
index 0000000000..5182dbb158
--- /dev/null
+++ b/t/t6004-rev-list-path-optim.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+test_description='git-rev-list trivial path optimization test'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+echo Hello > a &&
+git add a &&
+git commit -m "Initial commit" a
+'
+
+test_expect_success path-optimization '
+ commit=$(echo "Unchanged tree" | git-commit-tree "HEAD^{tree}" -p HEAD) &&
+ test $(git-rev-list $commit | wc -l) = 2 &&
+ test $(git-rev-list $commit -- . | wc -l) = 1
+'
+
+test_done
diff --git a/tag.c b/tag.c
index 74d0dabe5d..864ac1bb60 100644
--- a/tag.c
+++ b/tag.c
@@ -5,7 +5,7 @@ const char *tag_type = "tag";
struct object *deref_tag(struct object *o, const char *warn, int warnlen)
{
- while (o && o->type == TYPE_TAG)
+ while (o && o->type == OBJ_TAG)
o = parse_object(((struct tag *)o)->tagged->sha1);
if (!o && warn) {
if (!warnlen)
@@ -21,12 +21,12 @@ struct tag *lookup_tag(const unsigned char *sha1)
if (!obj) {
struct tag *ret = alloc_tag_node();
created_object(sha1, &ret->object);
- ret->object.type = TYPE_TAG;
+ ret->object.type = OBJ_TAG;
return ret;
}
if (!obj->type)
- obj->type = TYPE_TAG;
- if (obj->type != TYPE_TAG) {
+ obj->type = OBJ_TAG;
+ if (obj->type != OBJ_TAG) {
error("Object %s is a %s, not a tree",
sha1_to_hex(sha1), typename(obj->type));
return NULL;
diff --git a/tree.c b/tree.c
index 10236555cc..a6032e35ec 100644
--- a/tree.c
+++ b/tree.c
@@ -131,12 +131,12 @@ struct tree *lookup_tree(const unsigned char *sha1)
if (!obj) {
struct tree *ret = alloc_tree_node();
created_object(sha1, &ret->object);
- ret->object.type = TYPE_TREE;
+ ret->object.type = OBJ_TREE;
return ret;
}
if (!obj->type)
- obj->type = TYPE_TREE;
- if (obj->type != TYPE_TREE) {
+ obj->type = OBJ_TREE;
+ if (obj->type != OBJ_TREE) {
error("Object %s is a %s, not a tree",
sha1_to_hex(sha1), typename(obj->type));
return NULL;
@@ -216,11 +216,11 @@ struct tree *parse_tree_indirect(const unsigned char *sha1)
do {
if (!obj)
return NULL;
- if (obj->type == TYPE_TREE)
+ if (obj->type == OBJ_TREE)
return (struct tree *) obj;
- else if (obj->type == TYPE_COMMIT)
+ else if (obj->type == OBJ_COMMIT)
obj = &(((struct commit *) obj)->tree->object);
- else if (obj->type == TYPE_TAG)
+ else if (obj->type == OBJ_TAG)
obj = ((struct tag *) obj)->tagged;
else
return NULL;
diff --git a/unpack-objects.c b/unpack-objects.c
index 3b824b04a2..48c1ee7968 100644
--- a/unpack-objects.c
+++ b/unpack-objects.c
@@ -241,11 +241,6 @@ static void unpack_one(unsigned nr, unsigned total)
}
}
-/*
- * We unpack from the end, older files first. Now, usually
- * there are deltas etc, so we'll not actually write the
- * objects in that order, but we might as well try..
- */
static void unpack_all(void)
{
int i;
diff --git a/upload-pack.c b/upload-pack.c
index 94aa0dab48..07ecdb4281 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -182,6 +182,8 @@ static void create_pack_file(void)
ssize_t sz;
int pe, pu, pollsize;
+ reset_timeout();
+
pollsize = 0;
pe = pu = -1;
@@ -330,7 +332,7 @@ static int got_sha1(char *hex, unsigned char *sha1)
o = parse_object(sha1);
if (!o)
die("oops (%s)", sha1_to_hex(sha1));
- if (o->type == TYPE_COMMIT) {
+ if (o->type == OBJ_COMMIT) {
struct commit_list *parents;
if (o->flags & THEY_HAVE)
return 0;
@@ -461,7 +463,7 @@ static int send_ref(const char *refname, const unsigned char *sha1)
o->flags |= OUR_REF;
nr_our_refs++;
}
- if (o->type == TYPE_TAG) {
+ if (o->type == OBJ_TAG) {
o = deref_tag(o, refname, 0);
packet_write(1, "%s %s^{}\n", sha1_to_hex(o->sha1), refname);
}