summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2007-09-14 08:19:30 (GMT)
committerJunio C Hamano <gitster@pobox.com>2007-09-14 08:19:30 (GMT)
commit58f6fb53dd1104559f6f5507562a975c0ff079af (patch)
treee5d6efb5312abab35abf8a7b18aacc61776c6592
parentcbb390cd8f58ca6fc5c7b2c710425649b057b6d6 (diff)
parent09d5dc32fbdfa7bfd23fe377455445dd2605c3b9 (diff)
downloadgit-58f6fb53dd1104559f6f5507562a975c0ff079af.zip
git-58f6fb53dd1104559f6f5507562a975c0ff079af.tar.gz
git-58f6fb53dd1104559f6f5507562a975c0ff079af.tar.bz2
Merge branch 'jc/cachetree' into cr/reset
* jc/cachetree: Simplify cache API git-format-patch --in-reply-to: accept <message@id> with angle brackets git-add -u: do not barf on type changes Remove duplicate note about removing commits with git-filter-branch git-clone: improve error message if curl program is missing or not executable git.el: Allow the add and remove commands to be applied to ignored files. git.el: Allow selecting whether to display uptodate/unknown/ignored files. git.el: Keep the status buffer sorted by filename. hooks--update: Explicitly check for all zeros for a deleted ref.
-rw-r--r--Documentation/git-filter-branch.txt5
-rw-r--r--builtin-add.c2
-rw-r--r--builtin-apply.c2
-rw-r--r--builtin-log.c31
-rw-r--r--builtin-mv.c7
-rw-r--r--builtin-rm.c1
-rw-r--r--builtin-update-index.c9
-rw-r--r--contrib/emacs/git.el197
-rwxr-xr-xgit-clone.sh6
-rw-r--r--read-cache.c3
-rw-r--r--templates/hooks--update2
11 files changed, 184 insertions, 81 deletions
diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt
index 29bb8ce..c878ed3 100644
--- a/Documentation/git-filter-branch.txt
+++ b/Documentation/git-filter-branch.txt
@@ -220,11 +220,6 @@ git filter-branch --commit-filter '
fi' HEAD
------------------------------------------------------------------------------
-Note that the changes introduced by the commits, and not reverted by
-subsequent commits, will still be in the rewritten branch. If you want
-to throw out _changes_ together with the commits, you should use the
-interactive mode of gitlink:git-rebase[1].
-
The function 'skip_commits' is defined as follows:
--------------------------
diff --git a/builtin-add.c b/builtin-add.c
index 105a9f0..866d19d 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -98,11 +98,11 @@ static void update_callback(struct diff_queue_struct *q,
die("unexpacted diff status %c", p->status);
case DIFF_STATUS_UNMERGED:
case DIFF_STATUS_MODIFIED:
+ case DIFF_STATUS_TYPE_CHANGED:
add_file_to_cache(path, verbose);
break;
case DIFF_STATUS_DELETED:
remove_file_from_cache(path);
- cache_tree_invalidate_path(active_cache_tree, path);
if (verbose)
printf("remove '%s'\n", path);
break;
diff --git a/builtin-apply.c b/builtin-apply.c
index 976ec77..79a4852 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -2394,7 +2394,6 @@ static void remove_file(struct patch *patch, int rmdir_empty)
if (update_index) {
if (remove_file_from_cache(patch->old_name) < 0)
die("unable to remove %s from index", patch->old_name);
- cache_tree_invalidate_path(active_cache_tree, patch->old_name);
}
if (!cached) {
if (S_ISGITLINK(patch->old_mode)) {
@@ -2549,7 +2548,6 @@ static void create_file(struct patch *patch)
mode = S_IFREG | 0644;
create_one_file(path, mode, buf, size);
add_index_file(path, mode, buf, size);
- cache_tree_invalidate_path(active_cache_tree, path);
}
/* phase zero is to remove, phase one is to create */
diff --git a/builtin-log.c b/builtin-log.c
index fa81c25..c6cc3ae 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -437,6 +437,34 @@ static void gen_message_id(char *dest, unsigned int length, char *base)
(int)(email_end - email_start - 1), email_start + 1);
}
+static const char *clean_message_id(const char *msg_id)
+{
+ char ch;
+ const char *a, *z, *m;
+ char *n;
+ size_t len;
+
+ m = msg_id;
+ while ((ch = *m) && (isspace(ch) || (ch == '<')))
+ m++;
+ a = m;
+ z = NULL;
+ while ((ch = *m)) {
+ if (!isspace(ch) && (ch != '>'))
+ z = m;
+ m++;
+ }
+ if (!z)
+ die("insane in-reply-to: %s", msg_id);
+ if (++z == m)
+ return a;
+ len = z - a;
+ n = xmalloc(len + 1);
+ memcpy(n, a, len);
+ n[len] = 0;
+ return n;
+}
+
int cmd_format_patch(int argc, const char **argv, const char *prefix)
{
struct commit *commit;
@@ -625,7 +653,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
if (numbered)
rev.total = total + start_number - 1;
rev.add_signoff = add_signoff;
- rev.ref_message_id = in_reply_to;
+ if (in_reply_to)
+ rev.ref_message_id = clean_message_id(in_reply_to);
while (0 <= --nr) {
int shown;
commit = list[nr];
diff --git a/builtin-mv.c b/builtin-mv.c
index 3563216..b95b7d2 100644
--- a/builtin-mv.c
+++ b/builtin-mv.c
@@ -276,11 +276,8 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
add_file_to_cache(path, verbose);
}
- for (i = 0; i < deleted.nr; i++) {
- const char *path = deleted.items[i].path;
- remove_file_from_cache(path);
- cache_tree_invalidate_path(active_cache_tree, path);
- }
+ for (i = 0; i < deleted.nr; i++)
+ remove_file_from_cache(deleted.items[i].path);
if (active_cache_changed) {
if (write_cache(newfd, active_cache, active_nr) ||
diff --git a/builtin-rm.c b/builtin-rm.c
index 9a808c1..3b0677e 100644
--- a/builtin-rm.c
+++ b/builtin-rm.c
@@ -227,7 +227,6 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
if (remove_file_from_cache(path))
die("git-rm: unable to remove %s", path);
- cache_tree_invalidate_path(active_cache_tree, path);
}
if (show_only)
diff --git a/builtin-update-index.c b/builtin-update-index.c
index a7a4574..55fb679 100644
--- a/builtin-update-index.c
+++ b/builtin-update-index.c
@@ -195,11 +195,6 @@ static int process_path(const char *path)
int len;
struct stat st;
- /* We probably want to do this in remove_file_from_cache() and
- * add_cache_entry() instead...
- */
- cache_tree_invalidate_path(active_cache_tree, path);
-
/*
* First things first: get the stat information, to decide
* what to do about the pathname!
@@ -239,7 +234,6 @@ static int add_cacheinfo(unsigned int mode, const unsigned char *sha1,
return error("%s: cannot add to the index - missing --add option?",
path);
report("add '%s'", path);
- cache_tree_invalidate_path(active_cache_tree, path);
return 0;
}
@@ -284,7 +278,6 @@ static void update_one(const char *path, const char *prefix, int prefix_length)
die("Unable to mark file %s", path);
goto free_return;
}
- cache_tree_invalidate_path(active_cache_tree, path);
if (force_remove) {
if (remove_file_from_cache(p))
@@ -367,7 +360,6 @@ static void read_index_info(int line_termination)
free(path_name);
continue;
}
- cache_tree_invalidate_path(active_cache_tree, path_name);
if (!mode) {
/* mode == 0 means there is no such path -- remove */
@@ -474,7 +466,6 @@ static int unresolve_one(const char *path)
goto free_return;
}
- cache_tree_invalidate_path(active_cache_tree, path);
remove_file_from_cache(path);
if (add_cache_entry(ce_2, ADD_CACHE_OK_TO_ADD)) {
error("%s: cannot add our version to the index.", path);
diff --git a/contrib/emacs/git.el b/contrib/emacs/git.el
index 280557e..2d77fd4 100644
--- a/contrib/emacs/git.el
+++ b/contrib/emacs/git.el
@@ -97,6 +97,21 @@ if there is already one that displays the same directory."
:group 'git
:type 'string)
+(defcustom git-show-uptodate nil
+ "Whether to display up-to-date files."
+ :group 'git
+ :type 'boolean)
+
+(defcustom git-show-ignored nil
+ "Whether to display ignored files."
+ :group 'git
+ :type 'boolean)
+
+(defcustom git-show-unknown t
+ "Whether to display unknown files."
+ :group 'git
+ :type 'boolean)
+
(defface git-status-face
'((((class color) (background light)) (:foreground "purple"))
@@ -479,6 +494,27 @@ and returns the process output as a string."
(setf (git-fileinfo->orig-name info) nil)
(setf (git-fileinfo->needs-refresh info) t))))
+(defun git-set-filenames-state (status files state)
+ "Set the state of a list of named files."
+ (when files
+ (setq files (sort files #'string-lessp))
+ (let ((file (pop files))
+ (node (ewoc-nth status 0)))
+ (while (and file node)
+ (let ((info (ewoc-data node)))
+ (cond ((string-lessp (git-fileinfo->name info) file)
+ (setq node (ewoc-next status node)))
+ ((string-equal (git-fileinfo->name info) file)
+ (unless (eq (git-fileinfo->state info) state)
+ (setf (git-fileinfo->state info) state)
+ (setf (git-fileinfo->rename-state info) nil)
+ (setf (git-fileinfo->orig-name info) nil)
+ (setf (git-fileinfo->needs-refresh info) t))
+ (setq file (pop files)))
+ (t (setq file (pop files)))))))
+ (unless state ;; delete files whose state has been set to nil
+ (ewoc-filter status (lambda (info) (git-fileinfo->state info))))))
+
(defun git-state-code (code)
"Convert from a string to a added/deleted/modified state."
(case (string-to-char code)
@@ -532,19 +568,36 @@ and returns the process output as a string."
" " (git-escape-file-name (git-fileinfo->name info))
(git-rename-as-string info))))
-(defun git-insert-fileinfo (status info &optional refresh)
- "Insert INFO in the status buffer, optionally refreshing an existing one."
- (let ((node (and refresh
- (git-find-status-file status (git-fileinfo->name info)))))
- (setf (git-fileinfo->needs-refresh info) t)
- (when node ;preserve the marked flag
- (setf (git-fileinfo->marked info) (git-fileinfo->marked (ewoc-data node))))
- (if node (setf (ewoc-data node) info) (ewoc-enter-last status info))))
+(defun git-insert-info-list (status infolist)
+ "Insert a list of file infos in the status buffer, replacing existing ones if any."
+ (setq infolist (sort infolist
+ (lambda (info1 info2)
+ (string-lessp (git-fileinfo->name info1)
+ (git-fileinfo->name info2)))))
+ (let ((info (pop infolist))
+ (node (ewoc-nth status 0)))
+ (while info
+ (setf (git-fileinfo->needs-refresh info) t)
+ (cond ((not node)
+ (ewoc-enter-last status info)
+ (setq info (pop infolist)))
+ ((string-lessp (git-fileinfo->name (ewoc-data node))
+ (git-fileinfo->name info))
+ (setq node (ewoc-next status node)))
+ ((string-equal (git-fileinfo->name (ewoc-data node))
+ (git-fileinfo->name info))
+ ;; preserve the marked flag
+ (setf (git-fileinfo->marked info) (git-fileinfo->marked (ewoc-data node)))
+ (setf (ewoc-data node) info)
+ (setq info (pop infolist)))
+ (t
+ (ewoc-enter-before status node info)
+ (setq info (pop infolist)))))))
(defun git-run-diff-index (status files)
"Run git-diff-index on FILES and parse the results into STATUS.
Return the list of files that haven't been handled."
- (let ((refresh files))
+ (let (infolist)
(with-temp-buffer
(apply #'git-run-command t nil "diff-index" "-z" "-M" "HEAD" "--" files)
(goto-char (point-min))
@@ -558,13 +611,14 @@ Return the list of files that haven't been handled."
(new-name (match-string 8)))
(if new-name ; copy or rename
(if (eq ?C (string-to-char state))
- (git-insert-fileinfo status (git-create-fileinfo 'added new-name old-perm new-perm 'copy name) refresh)
- (git-insert-fileinfo status (git-create-fileinfo 'deleted name 0 0 'rename new-name) refresh)
- (git-insert-fileinfo status (git-create-fileinfo 'added new-name old-perm new-perm 'rename name)) refresh)
- (git-insert-fileinfo status (git-create-fileinfo (git-state-code state) name old-perm new-perm) refresh))
+ (push (git-create-fileinfo 'added new-name old-perm new-perm 'copy name) infolist)
+ (push (git-create-fileinfo 'deleted name 0 0 'rename new-name) infolist)
+ (push (git-create-fileinfo 'added new-name old-perm new-perm 'rename name) infolist))
+ (push (git-create-fileinfo (git-state-code state) name old-perm new-perm) infolist))
(setq files (delete name files))
- (when new-name (setq files (delete new-name files)))))))
- files)
+ (when new-name (setq files (delete new-name files))))))
+ (git-insert-info-list status infolist)
+ files))
(defun git-find-status-file (status file)
"Find a given file in the status ewoc and return its node."
@@ -576,16 +630,16 @@ Return the list of files that haven't been handled."
(defun git-run-ls-files (status files default-state &rest options)
"Run git-ls-files on FILES and parse the results into STATUS.
Return the list of files that haven't been handled."
- (let ((refresh files))
+ (let (infolist)
(with-temp-buffer
- (apply #'git-run-command t nil "ls-files" "-z" "-t" (append options (list "--") files))
+ (apply #'git-run-command t nil "ls-files" "-z" (append options (list "--") files))
(goto-char (point-min))
- (while (re-search-forward "\\([HMRCK?]\\) \\([^\0]*\\)\0" nil t 1)
- (let ((state (match-string 1))
- (name (match-string 2)))
- (git-insert-fileinfo status (git-create-fileinfo (or (git-state-code state) default-state) name) refresh)
- (setq files (delete name files))))))
- files)
+ (while (re-search-forward "\\([^\0]*\\)\0" nil t 1)
+ (let ((name (match-string 1)))
+ (push (git-create-fileinfo default-state name) infolist)
+ (setq files (delete name files)))))
+ (git-insert-info-list status infolist)
+ files))
(defun git-run-ls-unmerged (status files)
"Run git-ls-files -u on FILES and parse the results into STATUS."
@@ -594,9 +648,8 @@ Return the list of files that haven't been handled."
(goto-char (point-min))
(let (unmerged-files)
(while (re-search-forward "[0-7]\\{6\\} [0-9a-f]\\{40\\} [123]\t\\([^\0]+\\)\0" nil t)
- (let ((node (git-find-status-file status (match-string 1))))
- (when node (push (ewoc-data node) unmerged-files))))
- (git-set-files-state unmerged-files 'unmerged))))
+ (push (match-string 1) unmerged-files))
+ (git-set-filenames-state status unmerged-files 'unmerged))))
(defun git-get-exclude-files ()
"Get the list of exclude files to pass to git-ls-files."
@@ -608,34 +661,30 @@ Return the list of files that haven't been handled."
(push config files))
files))
+(defun git-run-ls-files-with-excludes (status files default-state &rest options)
+ "Run git-ls-files on FILES with appropriate --exclude-from options."
+ (let ((exclude-files (git-get-exclude-files)))
+ (apply #'git-run-ls-files status files default-state
+ (concat "--exclude-per-directory=" git-per-dir-ignore-file)
+ (append options (mapcar (lambda (f) (concat "--exclude-from=" f)) exclude-files)))))
+
(defun git-update-status-files (files &optional default-state)
"Update the status of FILES from the index."
(unless git-status (error "Not in git-status buffer."))
- (let* ((status git-status)
- (remaining-files
+ (unless files
+ (when git-show-uptodate (git-run-ls-files git-status nil 'uptodate "-c")))
+ (let* ((remaining-files
(if (git-empty-db-p) ; we need some special handling for an empty db
- (git-run-ls-files status files 'added "-c")
- (git-run-diff-index status files))))
- (git-run-ls-unmerged status files)
- (when (or (not files) remaining-files)
- (let ((exclude-files (git-get-exclude-files)))
- (setq remaining-files (apply #'git-run-ls-files status remaining-files 'unknown "-o"
- (concat "--exclude-per-directory=" git-per-dir-ignore-file)
- (mapcar (lambda (f) (concat "--exclude-from=" f)) exclude-files)))))
- ; mark remaining files with the default state (or remove them if nil)
- (when remaining-files
- (if default-state
- (ewoc-map (lambda (info)
- (when (member (git-fileinfo->name info) remaining-files)
- (git-set-files-state (list info) default-state))
- nil)
- status)
- (ewoc-filter status
- (lambda (info files)
- (not (member (git-fileinfo->name info) files)))
- remaining-files)))
+ (git-run-ls-files git-status files 'added "-c")
+ (git-run-diff-index git-status files))))
+ (git-run-ls-unmerged git-status files)
+ (when (or remaining-files (and git-show-unknown (not files)))
+ (setq remaining-files (git-run-ls-files-with-excludes git-status remaining-files 'unknown "-o")))
+ (when (or remaining-files (and git-show-ignored (not files)))
+ (setq remaining-files (git-run-ls-files-with-excludes git-status remaining-files 'ignored "-o" "-i")))
+ (git-set-filenames-state git-status remaining-files default-state)
(git-refresh-files)
- (git-refresh-ewoc-hf status)))
+ (git-refresh-ewoc-hf git-status)))
(defun git-marked-files ()
"Return a list of all marked files, or if none a list containing just the file at cursor position."
@@ -853,7 +902,7 @@ Return the list of files that haven't been handled."
(defun git-add-file ()
"Add marked file(s) to the index cache."
(interactive)
- (let ((files (git-get-filenames (git-marked-files-state 'unknown))))
+ (let ((files (git-get-filenames (git-marked-files-state 'unknown 'ignored))))
(unless files
(push (file-relative-name (read-file-name "File to add: " nil nil t)) files))
(apply #'git-run-command nil nil "update-index" "--add" "--" files)
@@ -871,7 +920,7 @@ Return the list of files that haven't been handled."
(defun git-remove-file ()
"Remove the marked file(s)."
(interactive)
- (let ((files (git-get-filenames (git-marked-files-state 'added 'modified 'unknown 'uptodate))))
+ (let ((files (git-get-filenames (git-marked-files-state 'added 'modified 'unknown 'uptodate 'ignored))))
(unless files
(push (file-relative-name (read-file-name "File to remove: " nil nil t)) files))
(if (yes-or-no-p
@@ -916,11 +965,41 @@ Return the list of files that haven't been handled."
(interactive)
(ewoc-filter git-status
(lambda (info)
- (not (or (eq (git-fileinfo->state info) 'ignored)
- (eq (git-fileinfo->state info) 'uptodate)))))
+ (case (git-fileinfo->state info)
+ ('ignored git-show-ignored)
+ ('uptodate git-show-uptodate)
+ ('unknown git-show-unknown)
+ (t t))))
(unless (ewoc-nth git-status 0) ; refresh header if list is empty
(git-refresh-ewoc-hf git-status)))
+(defun git-toggle-show-uptodate ()
+ "Toogle the option for showing up-to-date files."
+ (interactive)
+ (if (setq git-show-uptodate (not git-show-uptodate))
+ (git-refresh-status)
+ (git-remove-handled)))
+
+(defun git-toggle-show-ignored ()
+ "Toogle the option for showing ignored files."
+ (interactive)
+ (if (setq git-show-ignored (not git-show-ignored))
+ (progn
+ (git-run-ls-files-with-excludes git-status nil 'ignored "-o" "-i")
+ (git-refresh-files)
+ (git-refresh-ewoc-hf git-status))
+ (git-remove-handled)))
+
+(defun git-toggle-show-unknown ()
+ "Toogle the option for showing unknown files."
+ (interactive)
+ (if (setq git-show-unknown (not git-show-unknown))
+ (progn
+ (git-run-ls-files-with-excludes git-status nil 'unknown "-o")
+ (git-refresh-files)
+ (git-refresh-ewoc-hf git-status))
+ (git-remove-handled)))
+
(defun git-setup-diff-buffer (buffer)
"Setup a buffer for displaying a diff."
(let ((dir default-directory))
@@ -1146,7 +1225,8 @@ Return the list of files that haven't been handled."
(unless git-status-mode-map
(let ((map (make-keymap))
- (diff-map (make-sparse-keymap)))
+ (diff-map (make-sparse-keymap))
+ (toggle-map (make-sparse-keymap)))
(suppress-keymap map)
(define-key map "?" 'git-help)
(define-key map "h" 'git-help)
@@ -1170,6 +1250,7 @@ Return the list of files that haven't been handled."
(define-key map "q" 'git-status-quit)
(define-key map "r" 'git-remove-file)
(define-key map "R" 'git-resolve-file)
+ (define-key map "t" toggle-map)
(define-key map "T" 'git-toggle-all-marks)
(define-key map "u" 'git-unmark-file)
(define-key map "U" 'git-revert-file)
@@ -1186,6 +1267,11 @@ Return the list of files that haven't been handled."
(define-key diff-map "h" 'git-diff-file-merge-head)
(define-key diff-map "m" 'git-diff-file-mine)
(define-key diff-map "o" 'git-diff-file-other)
+ ; the toggle submap
+ (define-key toggle-map "u" 'git-toggle-show-uptodate)
+ (define-key toggle-map "i" 'git-toggle-show-ignored)
+ (define-key toggle-map "k" 'git-toggle-show-unknown)
+ (define-key toggle-map "m" 'git-toggle-all-marks)
(setq git-status-mode-map map)))
;; git mode should only run in the *git status* buffer
@@ -1207,6 +1293,9 @@ Commands:
(let ((status (ewoc-create 'git-fileinfo-prettyprint "" "")))
(set (make-local-variable 'git-status) status))
(set (make-local-variable 'list-buffers-directory) default-directory)
+ (make-local-variable 'git-show-uptodate)
+ (make-local-variable 'git-show-ignored)
+ (make-local-variable 'git-show-unknown)
(run-hooks 'git-status-mode-hook)))
(defun git-find-status-buffer (dir)
diff --git a/git-clone.sh b/git-clone.sh
index 18003ab..5e582fe 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -34,7 +34,11 @@ fi
http_fetch () {
# $1 = Remote, $2 = Local
- curl -nsfL $curl_extra_args "$1" >"$2"
+ curl -nsfL $curl_extra_args "$1" >"$2" ||
+ case $? in
+ 126|127) exit ;;
+ *) return $? ;;
+ esac
}
clone_dumb_http () {
diff --git a/read-cache.c b/read-cache.c
index 536f4d0..2e40a34 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -346,6 +346,7 @@ int remove_file_from_index(struct index_state *istate, const char *path)
int pos = index_name_pos(istate, path, strlen(path));
if (pos < 0)
pos = -pos-1;
+ cache_tree_invalidate_path(istate->cache_tree, path);
while (pos < istate->cache_nr && !strcmp(istate->cache[pos]->name, path))
remove_index_entry_at(istate, pos);
return 0;
@@ -430,7 +431,6 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
die("unable to add %s to index",path);
if (verbose)
printf("add '%s'\n", path);
- cache_tree_invalidate_path(istate->cache_tree, path);
return 0;
}
@@ -698,6 +698,7 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e
int ok_to_replace = option & ADD_CACHE_OK_TO_REPLACE;
int skip_df_check = option & ADD_CACHE_SKIP_DFCHECK;
+ cache_tree_invalidate_path(istate->cache_tree, ce->name);
pos = index_name_pos(istate, ce->name, ntohs(ce->ce_flags));
/* existing match? Just replace it. */
diff --git a/templates/hooks--update b/templates/hooks--update
index 9d3795c..d8c7626 100644
--- a/templates/hooks--update
+++ b/templates/hooks--update
@@ -42,7 +42,7 @@ fi
# --- Check types
# if $newrev is 0000...0000, it's a commit to delete a branch
-if [ -z "${newrev##0*}" ]; then
+if [ "$newrev" = "0000000000000000000000000000000000000000" ]; then
newrev_type=commit
else
newrev_type=$(git-cat-file -t $newrev)