summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/git-commit-script.txt49
-rw-r--r--Documentation/git-ls-remote-script.txt64
-rw-r--r--Documentation/git.txt24
-rw-r--r--Makefile1
-rw-r--r--apply.c4
-rw-r--r--cache.h12
-rw-r--r--clone-pack.c2
-rw-r--r--commit.c33
-rw-r--r--commit.h1
-rw-r--r--connect.c14
-rw-r--r--convert-cache.c4
-rw-r--r--csum-file.h2
-rw-r--r--diff.c7
-rwxr-xr-xgit-cherry35
-rwxr-xr-xgit-commit-script127
-rwxr-xr-xgit-format-patch-script22
-rwxr-xr-xgit-ls-remote-script50
-rwxr-xr-xgit-push-script63
-rwxr-xr-xgit-rebase-script25
-rwxr-xr-xgit-reset-script8
-rwxr-xr-xgit-revert-script37
-rw-r--r--pack-check.c2
-rw-r--r--pkt-line.h2
-rw-r--r--refs.c6
-rw-r--r--rev-list.c23
-rw-r--r--rev-parse.c3
-rw-r--r--rsh.c8
-rw-r--r--sha1_file.c2
-rw-r--r--tar-tree.c4
-rw-r--r--tools/mailsplit.c2
30 files changed, 516 insertions, 120 deletions
diff --git a/Documentation/git-commit-script.txt b/Documentation/git-commit-script.txt
new file mode 100644
index 0000000000..bb559d70a5
--- /dev/null
+++ b/Documentation/git-commit-script.txt
@@ -0,0 +1,49 @@
+git-commit-script(1)
+====================
+v0.99.4, Aug 2005
+
+NAME
+----
+git-commit-script - Record your changes
+
+SYNOPSIS
+--------
+'git commit' [-a] [(-c | -C) <commit> | -F <file> | -m <msg>] <file>...
+
+DESCRIPTION
+-----------
+Updates the index file for given paths, or all modified files if
+'-a' is specified, and makes a commit object. The command
+VISUAL and EDITOR environment variables to edit the commit log
+message.
+
+OPTIONS
+-------
+-a::
+ Update all paths in the index file.
+
+-c or -C <commit>::
+ Take existing commit object, and reuse the log message
+ and the authorship information (including the timestamp)
+ when creating the commit. With '-C', the editor is not
+ invoked; with '-c' the user can further edit the commit
+ message.
+
+-F <file>::
+ Take the commit message from the given file. Use '-' to
+ read the message from the standard input.
+
+-m <msg>::
+ Use the given <msg> as the commit message.
+
+<file>...::
+ Update specified paths in the index file.
+
+
+Author
+------
+Written by Linus Torvalds <torvalds@osdl.org>
+
+GIT
+---
+Part of the link:git.html[git] suite
diff --git a/Documentation/git-ls-remote-script.txt b/Documentation/git-ls-remote-script.txt
new file mode 100644
index 0000000000..0b98e6a9f4
--- /dev/null
+++ b/Documentation/git-ls-remote-script.txt
@@ -0,0 +1,64 @@
+git-ls-remote-script(1)
+=======================
+v0.1, May 2005
+
+NAME
+----
+git-ls-remote-script - Look at references other repository has.
+
+
+SYNOPSIS
+--------
+'git-ls-remote' [--heads] [--tags] <repository> <refs>...
+
+DESCRIPTION
+-----------
+Displays the references other repository has.
+
+
+OPTIONS
+-------
+--heads --tags::
+ Limit to only refs/heads and refs/tags, respectively.
+ These options are _not_ mutually exclusive; when given
+ both, references stored in refs/heads and refs/tags are
+ displayed.
+
+<repository>::
+ Location of the repository. The shorthand defined in
+ $GIT_DIR/branches/ can be used.
+
+<refs>...::
+ When unspecified, all references, after filtering done
+ with --heads and --tags, are shown. When <refs>... are
+ specified, only references matching the given patterns
+ are displayed.
+
+EXAMPLES
+--------
+
+ $ git ls-remote --tags ./.
+ d6602ec5194c87b0fc87103ca4d67251c76f233a refs/tags/v0.99
+ f25a265a342aed6041ab0cc484224d9ca54b6f41 refs/tags/v0.99.1
+ 7ceca275d047c90c0c7d5afb13ab97efdf51bd6e refs/tags/v0.99.3
+ c5db5456ae3b0873fc659c19fafdde22313cc441 refs/tags/v0.99.2
+ 0918385dbd9656cab0d1d81ba7453d49bbc16250 refs/tags/junio-gpg-pub
+ $ git ls-remote http://www.kernel.org/pub/scm/git/git.git master pu rc
+ 5fe978a5381f1fbad26a80e682ddd2a401966740 refs/heads/master
+ c781a84b5204fb294c9ccc79f8b3baceeb32c061 refs/heads/pu
+ b1d096f2926c4e37c9c0b6a7bf2119bedaa277cb refs/heads/rc
+ $ echo http://www.kernel.org/pub/scm/git/git.git >.git/branches/public
+ $ git ls-remote --tags public v\*
+ d6602ec5194c87b0fc87103ca4d67251c76f233a refs/tags/v0.99
+ f25a265a342aed6041ab0cc484224d9ca54b6f41 refs/tags/v0.99.1
+ c5db5456ae3b0873fc659c19fafdde22313cc441 refs/tags/v0.99.2
+ 7ceca275d047c90c0c7d5afb13ab97efdf51bd6e refs/tags/v0.99.3
+
+Author
+------
+Written by Junio C Hamano <junkio@cox.net>
+
+GIT
+---
+Part of the link:git.html[git] suite
+
diff --git a/Documentation/git.txt b/Documentation/git.txt
index d18cf5ec16..1308eb675d 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -34,6 +34,10 @@ the repository, the cache and the working fileset, those that
interrogate and compare them, and those that moves objects and
references between repositories.
+In addition, git itself comes with a spartan set of porcelain
+commands. They are usable but are not meant to compete with real
+Porcelains.
+
There are also some ancilliary programs that can be viewed as useful
aids for using the core commands but which are unlikely to be used by
SCMs layered over git.
@@ -128,14 +132,6 @@ link:git-clone-pack.html[git-clone-pack]::
Clones a repository into the current repository (engine
for ssh and local transport)
-link:git-fetch-script.html[git-fetch-script]::
- Download from a remote repository via various protocols
- (user interface).
-
-link:git-pull-script.html[git-pull-script]::
- Fetch from and merge with a remote repository via
- various protocols (user interface).
-
link:git-http-pull.html[git-http-pull]::
Downloads a remote GIT repository via HTTP
@@ -169,6 +165,18 @@ link:git-update-server-info.html[git-update-server-info]::
clients discover references and packs on it.
+Porcelainish Commands
+---------------------
+link:git-fetch-script.html[git-fetch-script]::
+ Download from a remote repository via various protocols.
+
+link:git-pull-script.html[git-pull-script]::
+ Fetch from and merge with a remote repository.
+
+link:git-commit-script.html[git-commit-script]::
+ Record changes to the repository.
+
+
Ancilliary Commands
-------------------
Manipulators:
diff --git a/Makefile b/Makefile
index df5f8c0dc3..e0ea88fbae 100644
--- a/Makefile
+++ b/Makefile
@@ -70,6 +70,7 @@ SCRIPTS=git git-apply-patch-script git-merge-one-file-script git-prune-script \
SCRIPTS += git-count-objects-script
# SCRIPTS += git-send-email-script
+SCRIPTS += git-revert-script
PROG= git-update-cache git-diff-files git-init-db git-write-tree \
git-read-tree git-commit-tree git-cat-file git-fsck-cache \
diff --git a/apply.c b/apply.c
index c671d9e86c..81607c0fb6 100644
--- a/apply.c
+++ b/apply.c
@@ -563,7 +563,7 @@ static int find_header(char *line, unsigned long size, int *hdrsize, struct patc
struct fragment dummy;
if (parse_fragment_header(line, len, &dummy) < 0)
continue;
- error("patch fragment without header at line %d: %.*s", linenr, len-1, line);
+ error("patch fragment without header at line %d: %.*s", linenr, (int)len-1, line);
}
if (size < len + 6)
@@ -968,7 +968,7 @@ static int apply_fragments(struct buffer_desc *desc, struct patch *patch)
while (frag) {
if (apply_one_fragment(desc, frag) < 0)
- return error("patch failed: %s:%d", patch->old_name, frag->oldpos);
+ return error("patch failed: %s:%ld", patch->old_name, frag->oldpos);
frag = frag->next;
}
return 0;
diff --git a/cache.h b/cache.h
index 957e2ca7ca..efd2a2c595 100644
--- a/cache.h
+++ b/cache.h
@@ -40,6 +40,10 @@
#define NORETURN
#endif
+#ifndef __attribute__
+#define __attribute(x)
+#endif
+
/*
* Intensive research over the course of many years has shown that
* port 9418 is totally unused by anything else. Or
@@ -171,8 +175,8 @@ extern void rollback_index_file(struct cache_file *);
#define TYPE_CHANGED 0x0040
/* Return a statically allocated filename matching the sha1 signature */
-extern char *mkpath(const char *fmt, ...);
-extern char *git_path(const char *fmt, ...);
+extern char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
+extern char *git_path(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
extern char *sha1_file_name(const unsigned char *sha1);
extern char *sha1_pack_name(const unsigned char *sha1);
extern char *sha1_pack_index_name(const unsigned char *sha1);
@@ -218,8 +222,8 @@ extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */
/* General helper functions */
extern void usage(const char *err) NORETURN;
-extern void die(const char *err, ...) NORETURN;
-extern int error(const char *err, ...);
+extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
+extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
extern int base_name_compare(const char *name1, int len1, int mode1, const char *name2, int len2, int mode2);
extern int cache_name_compare(const char *name1, int len1, const char *name2, int len2);
diff --git a/clone-pack.c b/clone-pack.c
index e9c20dee71..49820c6579 100644
--- a/clone-pack.c
+++ b/clone-pack.c
@@ -30,7 +30,7 @@ static int is_master(struct ref *ref)
static void write_one_ref(struct ref *ref)
{
- char *path = git_path(ref->name);
+ char *path = git_path("%s", ref->name);
int fd;
char *hex;
diff --git a/commit.c b/commit.c
index 3ac421ac34..59e93d4590 100644
--- a/commit.c
+++ b/commit.c
@@ -33,6 +33,8 @@ enum cmit_fmt get_commit_format(const char *arg)
return CMIT_FMT_SHORT;
if (!strcmp(arg, "=full"))
return CMIT_FMT_FULL;
+ if (!strcmp(arg, "=oneline"))
+ return CMIT_FMT_ONELINE;
die("invalid --pretty format");
}
@@ -350,6 +352,8 @@ static int add_user_info(const char *what, enum cmit_fmt fmt, char *buf, const c
unsigned long time;
int tz, ret;
+ if (fmt == CMIT_FMT_ONELINE)
+ return 0;
date = strchr(line, '>');
if (!date)
return 0;
@@ -373,6 +377,9 @@ static int is_empty_line(const char *line, int len)
static int add_parent_info(enum cmit_fmt fmt, char *buf, const char *line, int parents)
{
int offset = 0;
+
+ if (fmt == CMIT_FMT_ONELINE)
+ return offset;
switch (parents) {
case 1:
break;
@@ -393,6 +400,7 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, const char *msg, unsigned l
int hdr = 1, body = 0;
unsigned long offset = 0;
int parents = 0;
+ int indent = (fmt == CMIT_FMT_ONELINE) ? 0 : 4;
for (;;) {
const char *line = msg;
@@ -416,7 +424,8 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, const char *msg, unsigned l
if (hdr) {
if (linelen == 1) {
hdr = 0;
- buf[offset++] = '\n';
+ if (fmt != CMIT_FMT_ONELINE)
+ buf[offset++] = '\n';
continue;
}
if (fmt == CMIT_FMT_RAW) {
@@ -446,13 +455,23 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, const char *msg, unsigned l
} else {
body = 1;
}
- memset(buf + offset, ' ', 4);
- memcpy(buf + offset + 4, line, linelen);
- offset += linelen + 4;
+
+ memset(buf + offset, ' ', indent);
+ memcpy(buf + offset + indent, line, linelen);
+ offset += linelen + indent;
+ if (fmt == CMIT_FMT_ONELINE)
+ break;
+ }
+ if (fmt == CMIT_FMT_ONELINE) {
+ /* We do not want the terminating newline */
+ if (buf[offset - 1] == '\n')
+ offset--;
+ }
+ else {
+ /* Make sure there is an EOLN */
+ if (buf[offset - 1] != '\n')
+ buf[offset++] = '\n';
}
- /* Make sure there is an EOLN */
- if (buf[offset - 1] != '\n')
- buf[offset++] = '\n';
buf[offset] = '\0';
return offset;
}
diff --git a/commit.h b/commit.h
index c24ab21061..5d179d4dc8 100644
--- a/commit.h
+++ b/commit.h
@@ -40,6 +40,7 @@ enum cmit_fmt {
CMIT_FMT_DEFAULT = CMIT_FMT_MEDIUM,
CMIT_FMT_SHORT,
CMIT_FMT_FULL,
+ CMIT_FMT_ONELINE,
};
extern enum cmit_fmt get_commit_format(const char *arg);
diff --git a/connect.c b/connect.c
index 20b80a1b54..a6657b1384 100644
--- a/connect.c
+++ b/connect.c
@@ -166,7 +166,8 @@ static int match_explicit_refs(struct ref *src, struct ref *dst,
if (matched_src)
break;
errs = 1;
- error("src refspec %s does not match any.");
+ error("src refspec %s does not match any.",
+ rs[i].src);
break;
default:
errs = 1;
@@ -381,8 +382,15 @@ int git_connect(int fd[2], char *url, const char *prog)
close(pipefd[0][1]);
close(pipefd[1][0]);
close(pipefd[1][1]);
- if (protocol == PROTO_SSH)
- execlp("ssh", "ssh", host, command, NULL);
+ if (protocol == PROTO_SSH) {
+ const char *ssh = getenv("GIT_SSH") ? : "ssh";
+ const char *ssh_basename = strrchr(ssh, '/');
+ if (!ssh_basename)
+ ssh_basename = ssh;
+ else
+ ssh_basename++;
+ execlp(ssh, ssh_basename, host, command, NULL);
+ }
else
execlp("sh", "sh", "-c", command, NULL);
die("exec failed");
diff --git a/convert-cache.c b/convert-cache.c
index 8916a3692f..95f0302f7a 100644
--- a/convert-cache.c
+++ b/convert-cache.c
@@ -60,7 +60,7 @@ static void convert_ascii_sha1(void *buffer)
struct entry *entry;
if (get_sha1_hex(buffer, sha1))
- die("expected sha1, got '%s'", buffer);
+ die("expected sha1, got '%s'", (char*) buffer);
entry = convert_entry(sha1);
memcpy(buffer, sha1_to_hex(entry->new_sha1), 40);
}
@@ -272,7 +272,7 @@ static void convert_commit(void *buffer, unsigned long size, unsigned char *resu
unsigned long orig_size = size;
if (memcmp(buffer, "tree ", 5))
- die("Bad commit '%s'", buffer);
+ die("Bad commit '%s'", (char*) buffer);
convert_ascii_sha1(buffer+5);
buffer += 46; /* "tree " + "hex sha1" + "\n" */
while (!memcmp(buffer, "parent ", 7)) {
diff --git a/csum-file.h b/csum-file.h
index 776cfb152a..3ad1a992a7 100644
--- a/csum-file.h
+++ b/csum-file.h
@@ -11,7 +11,7 @@ struct sha1file {
};
extern struct sha1file *sha1fd(int fd, const char *name);
-extern struct sha1file *sha1create(const char *fmt, ...);
+extern struct sha1file *sha1create(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
extern int sha1close(struct sha1file *, unsigned char *, int);
extern int sha1write(struct sha1file *, void *, unsigned int);
extern int sha1write_compressed(struct sha1file *, void *, unsigned int);
diff --git a/diff.c b/diff.c
index 9962fc359c..3e52fec187 100644
--- a/diff.c
+++ b/diff.c
@@ -134,8 +134,8 @@ static void builtin_diff(const char *name_a,
int complete_rewrite)
{
int i, next_at, cmd_size;
- const char *diff_cmd = "diff -L%s%s -L%s%s";
- const char *diff_arg = "%s %s||:"; /* "||:" is to return 0 */
+ const char *const diff_cmd = "diff -L%s%s -L%s%s";
+ const char *const diff_arg = "%s %s||:"; /* "||:" is to return 0 */
const char *input_name_sq[2];
const char *path0[2];
const char *path1[2];
@@ -782,7 +782,8 @@ static void diff_flush_raw(struct diff_filepair *p,
char status[10];
if (line_termination) {
- const char *err = "path %s cannot be expressed without -z";
+ const char *const err =
+ "path %s cannot be expressed without -z";
if (strchr(p->one->path, line_termination) ||
strchr(p->one->path, inter_name_termination))
die(err, p->one->path);
diff --git a/git-cherry b/git-cherry
index f3bfbf3a4e..e186363647 100755
--- a/git-cherry
+++ b/git-cherry
@@ -3,7 +3,9 @@
# Copyright (c) 2005 Junio C Hamano.
#
-usage="usage: $0 "'<upstream> [<head>]
+. git-sh-setup-script || die "Not a git archive."
+
+usage="usage: $0 "'[-v] <upstream> [<head>]
__*__*__*__*__> <upstream>
/
@@ -18,29 +20,38 @@ upstream, it is shown on the standard output.
The output is intended to be used as:
OLD_HEAD=$(git-rev-parse HEAD)
- git-rev-parse linus >${GIT_DIR-.}/HEAD
- git-cherry linus OLD_HEAD |
+ git-rev-parse upstream >${GIT_DIR-.}/HEAD
+ git-cherry upstream $OLD_HEAD |
while read commit
do
GIT_EXTERNAL_DIFF=git-apply-patch-script git-diff-tree -p "$commit" &&
- git-commit-script -m "$commit"
+ git-commit-script -C "$commit"
done
'
+case "$1" in -v) verbose=t; shift ;; esac
+
+case "$#,$1" in
+1,*..*)
+ upstream=$(expr "$1" : '\(.*\)\.\.') ours=$(expr "$1" : '.*\.\.\(.*\)$')
+ set x "$upstream" "$ours"
+ shift ;;
+esac
+
case "$#" in
-1) linus=`git-rev-parse --verify "$1"` &&
- junio=`git-rev-parse --verify HEAD` || exit
+1) upstream=`git-rev-parse --verify "$1"` &&
+ ours=`git-rev-parse --verify HEAD` || exit
;;
-2) linus=`git-rev-parse --verify "$1"` &&
- junio=`git-rev-parse --verify "$2"` || exit
+2) upstream=`git-rev-parse --verify "$1"` &&
+ ours=`git-rev-parse --verify "$2"` || exit
;;
*) echo >&2 "$usage"; exit 1 ;;
esac
# Note that these list commits in reverse order;
# not that the order in inup matters...
-inup=`git-rev-list ^$junio $linus` &&
-ours=`git-rev-list $junio ^$linus` || exit
+inup=`git-rev-list ^$ours $upstream` &&
+ours=`git-rev-list $ours ^$upstream` || exit
tmp=.cherry-tmp$$
patch=$tmp-patch
@@ -74,6 +85,10 @@ do
else
sign=+
fi
+ case "$verbose" in
+ t)
+ c=$(git-rev-list --pretty=oneline --max-count=1 $c)
+ esac
case "$O" in
'') O="$sign $c" ;;
*) O="$sign $c$LF$O" ;;
diff --git a/git-commit-script b/git-commit-script
index 1d59f46b94..24ec446a9d 100755
--- a/git-commit-script
+++ b/git-commit-script
@@ -6,44 +6,105 @@
. git-sh-setup-script || die "Not a git archive"
usage () {
- die 'git commit [--all] [-m existing-commit] [<path>...]'
+ die 'git commit [-a] [-m <message>] [-F <logfile>] [(-C|-c) <commit>] [<path>...]'
}
-files=()
-while case "$#" in 0) break ;; esac
+all= logfile= use_commit= no_edit= log_given= log_message=
+while case "$#" in 0) break;; esac
do
- case "$1" in
- -m) shift
- case "$#" in
- 0) usage ;;
- *) use_commit=`git-rev-parse --verify "$1"` ||
- exit ;;
- esac
- ;;
- --all)
- files=($(git-diff-files --name-only))\
- ;;
- *) break
- ;;
- esac
+ case "$1" in
+ -a|--a|--al|--all)
+ all=t
+ shift ;;
+ -F=*|--f=*|--fi=*|--fil=*|--file=*)
+ log_given=t$log_given
+ logfile=`expr "$1" : '-[^=]*=\(.*\)'`
+ no_edit=t
+ shift ;;
+ -F|--f|--fi|--fil|--file)
+ case "$#" in 1) usage ;; esac; shift
+ log_given=t$log_given
+ logfile="$1"
+ no_edit=t
+ shift ;;
+ -m=*|--m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*)
+ log_given=t$log_given
+ log_message=`expr "$1" : '-[^=]*=\(.*\)'`
+ no_edit=t
+ shift ;;
+ -m|--m|--me|--mes|--mess|--messa|--messag|--message)
+ case "$#" in 1) usage ;; esac; shift
+ log_given=t$log_given
+ log_message="$1"
+ no_edit=t
+ shift ;;
+ -c=*|--ree=*|--reed=*|--reedi=*|--reedit=*|--reedit-=*|--reedit-m=*|\
+ --reedit-me=*|--reedit-mes=*|--reedit-mess=*|--reedit-messa=*|\
+ --reedit-messag=*|--reedit-message=*)
+ log_given=t$log_given
+ use_commit=`expr "$1" : '-[^=]*=\(.*\)'`
+ shift ;;
+ -c|--ree|--reed|--reedi|--reedit|--reedit-|--reedit-m|--reedit-me|\
+ --reedit-mes|--reedit-mess|--reedit-messa|--reedit-messag|--reedit-message)
+ case "$#" in 1) usage ;; esac; shift
+ log_given=t$log_given
+ use_commit="$1"
+ shift ;;
+ -C=*|--reu=*|--reus=*|--reuse=*|--reuse-=*|--reuse-m=*|--reuse-me=*|\
+ --reuse-mes=*|--reuse-mess=*|--reuse-messa=*|--reuse-messag=*|\
+ --reuse-message=*)
+ log_given=t$log_given
+ use_commit=`expr "$1" : '-[^=]*=\(.*\)'`
+ no_edit=t
+ shift ;;
+ -C|--reu|--reus|--reuse|--reuse-|--reuse-m|--reuse-me|--reuse-mes|\
+ --reuse-mess|--reuse-messa|--reuse-messag|--reuse-message)
+ case "$#" in 1) usage ;; esac; shift
+ log_given=t$log_given
+ use_commit="$1"
+ no_edit=t
+ shift ;;
+ --)
shift
+ break ;;
+ -*)
+ usage ;;
+ *)
+ break ;;
+ esac
done
-git-update-cache -q --refresh -- "$@" "${files[@]}" || exit 1
+case "$log_given" in
+tt*)
+ die "Only one of -c/-C/-F/-m can be used." ;;
+esac
+
+case "$all" in
+t)
+ git-diff-files --name-only -z |
+ xargs -0 git-update-cache -q -- || exit 1 ;;
+esac
+git-update-cache -q --refresh -- "$@" || exit 1
+
PARENTS="-p HEAD"
if [ ! -r "$GIT_DIR/HEAD" ]; then
if [ -z "$(git-ls-files)" ]; then
echo Nothing to commit 1>&2
exit 1
fi
- (
+ {
echo "#"
echo "# Initial commit"
+ case "$no_edit" in
+ t) echo "# (ignoring your commit message for initial commit)"
+ no_edit=
+ esac
echo "#"
git-ls-files | sed 's/^/# New file: /'
echo "#"
- ) > .editmsg
+ } >.editmsg
PARENTS=""
+ no_edit=
else
if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
echo "#"
@@ -51,8 +112,25 @@ else
echo "# If this is not correct, please remove the file"
echo "# $GIT_DIR/MERGE_HEAD"
echo "# and try again"
+ case "$no_edit" in
+ t) echo "# (ignoring your commit message for merge commit)"
+ no_edit=
+ esac
echo "#"
PARENTS="-p HEAD -p MERGE_HEAD"
+ elif test "$log_message" != ''
+ then
+ echo "$log_message"
+ elif test "$logfile" != ""
+ then
+ if test "$logfile" = -
+ then
+ test -t 0 &&
+ echo >&2 "(reading log message from standard input)"
+ cat
+ else
+ cat <"$logfile"
+ fi
elif test "$use_commit" != ""
then
pick_author_script='
@@ -92,17 +170,22 @@ then
rm .editmsg
exit 1
fi
-case "$use_commit" in
+case "$no_edit" in
'')
${VISUAL:-${EDITOR:-vi}} .editmsg
;;
esac
grep -v '^#' < .editmsg | git-stripspace > .cmitmsg
-[ -s .cmitmsg ] &&
+if test -s .cmitmsg
+then
tree=$(git-write-tree) &&
commit=$(cat .cmitmsg | git-commit-tree $tree $PARENTS) &&
echo $commit > "$GIT_DIR/HEAD" &&
rm -f -- "$GIT_DIR/MERGE_HEAD"
+else
+ echo >&2 "* no commit message? aborting commit."
+ false
+fi
ret="$?"
rm -f .cmitmsg .editmsg
exit "$ret"
diff --git a/git-format-patch-script b/git-format-patch-script
index 51e8af0acb..c0081697da 100755
--- a/git-format-patch-script
+++ b/git-format-patch-script
@@ -3,6 +3,8 @@
# Copyright (c) 2005 Junio C Hamano
#
+. git-sh-setup-script || die "Not a git archive."
+
usage () {
echo >&2 "usage: $0"' [-n] [-o dir] [--mbox] [--check] [-<diff options>...] upstream [ our-head ]
@@ -60,13 +62,20 @@ do
shift
done
+revpair=
case "$#" in
-2) linus="$1" junio="$2" ;;
-1) linus="$1" junio=HEAD ;;
-*) usage ;;
+2)
+ revpair="$1..$2" ;;
+1)
+ case "$1" in
+ *..*)
+ revpair="$1";;
+ *)
+ revpair="$1..HEAD";;
+ esac ;;
+*)
+ usage ;;
esac
-junio=`git-rev-parse --verify "$junio"`
-linus=`git-rev-parse --verify "$linus"`
me=`git-var GIT_AUTHOR_IDENT | sed -e 's/>.*/>/'`
@@ -108,7 +117,8 @@ _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
stripCommitHead='/^'"$_x40"' (from '"$_x40"')$/d'
-git-rev-list --merge-order "$junio" "^$linus" >$series
+git-rev-list --no-merges --merge-order \
+ $(git-rev-parse --revs-only "$revpair") >$series
total=`wc -l <$series | tr -dc "[0-9]"`
i=$total
while read commit
diff --git a/git-ls-remote-script b/git-ls-remote-script
index 31cdac8bfe..75f6027866 100755
--- a/git-ls-remote-script
+++ b/git-ls-remote-script
@@ -3,7 +3,7 @@
. git-sh-setup-script || die "Not a git archive"
usage () {
- echo >&2 "usage: $0 [--heads] [--tags] [--overwrite | --store] repo"
+ echo >&2 "usage: $0 [--heads] [--tags] <repository> <refs>..."
exit 1;
}
@@ -12,10 +12,6 @@ do
case "$1" in
-h|--h|--he|--hea|--head|--heads)
heads=heads; shift ;;
- -o|--o|--ov|--ove|--over|--overw|--overwr|--overwri|--overwrit|--overwrite)
- overwrite=overwrite; shift ;;
- -s|--s|--st|--sto|--stor|--store)
- store=store; shift ;;
-t|--t|--ta|--tag|--tags)
tags=tags; shift ;;
--)
@@ -27,15 +23,15 @@ do
esac
done
-case "$#" in 1) ;; *) usage ;; esac
-case ",$store,$overwrite," in *,,*) ;; *) usage ;; esac
+case "$#" in 0) usage ;; esac
case ",$heads,$tags," in
,,,) heads=heads tags=tags other=other ;;
esac
-. git-parse-remote "$@"
+. git-parse-remote "$1"
peek_repo="$_remote_repo"
+shift
tmp=.ls-remote-$$
trap "rm -fr $tmp-*" 0 1 2 3 15
@@ -65,7 +61,7 @@ rsync://* )
git-peek-remote "$peek_repo"
;;
esac |
-
+sort -t ' ' -k 2 |
while read sha1 path
do
case "$path" in
@@ -82,23 +78,23 @@ do
*)
continue;;
esac
-
- echo "$sha1 $path"
-
- case "$path,$store,$overwrite," in
- *,,, | HEAD,*) continue ;;
+ case "$#" in
+ 0)
+ match=yes ;;
+ *)
+ match=no
+ for pat
+ do
+ case "/$path" in
+ */$pat )
+ match=yes
+ break ;;
+ esac
+ done
esac
-
- if test -f "$GIT_DIR/$path" && test "$overwrite" == ""
- then
- continue
- fi
-
- # Be careful. We may not have that object yet!
- if git-cat-file -t "$sha1" >/dev/null 2>&1
- then
- echo "$sha1" >"$GIT_DIR/$path"
- else
- echo >&2 "* You have not fetched updated $path ($sha1)."
- fi
+ case "$match" in
+ no)
+ continue ;;
+ esac
+ echo "$sha1 $path"
done
diff --git a/git-push-script b/git-push-script
index 80e922bb5d..70fa9684a5 100755
--- a/git-push-script
+++ b/git-push-script
@@ -1,3 +1,64 @@
#!/bin/sh
. git-sh-setup-script || die "Not a git archive"
-git-send-pack "$@"
+
+# Parse out parameters and then stop at remote, so that we can
+# translate it using .git/branches information
+has_all=
+has_force=
+has_exec=
+remote=
+
+while case "$#" in 0) break ;; esac
+do
+ case "$1" in
+ --all)
+ has_all=--all ;;
+ --force)
+ has_force=--force ;;
+ --exec=*)
+ has_exec="$1" ;;
+ -*)
+ die "Unknown parameter $1" ;;
+ *)
+ remote="$1"
+ shift
+ set x "$@"
+ shift
+ break ;;
+ esac
+ shift
+done
+
+case "$remote" in
+*:* | /* | ../* | ./* )
+ # An URL, host:/path/to/git, absolute and relative paths.
+ ;;
+* )
+ # Shorthand
+ if expr "$remote" : '..*/..*' >/dev/null
+ then
+ # a short-hand followed by a trailing path
+ shorthand=$(expr "$remote" : '\([^/]*\)')
+ remainder=$(expr "$remote" : '[^/]*\(/.*\)$')
+ else
+ shorthand="$remote"
+ remainder=
+ fi
+ remote=$(sed -e 's/#.*//' "$GIT_DIR/branches/$remote") &&
+ expr "$remote" : '..*:' >/dev/null &&
+ remote="$remote$remainder" ||
+ die "Cannot parse remote $remote"
+ ;;
+esac
+
+case "$remote" in
+http://* | https://* | git://* | rsync://* )
+ die "Cannot push to $remote" ;;
+esac
+
+set x "$remote" "$@"; shift
+test "$has_all" && set x "$has_all" "$@" && shift
+test "$has_force" && set x "$has_force" "$@" && shift
+test "$has_exec" && set x "$has_exec" "$@" && shift
+
+exec git-send-pack "$@"
diff --git a/git-rebase-script b/git-rebase-script
index 5b791c6bda..7779813d11 100755
--- a/git-rebase-script
+++ b/git-rebase-script
@@ -3,25 +3,32 @@
# Copyright (c) 2005 Junio C Hamano.
#
+. git-sh-setup-script || die "Not a git archive."
+
usage="usage: $0 "'<upstream> [<head>]
Uses output from git-cherry to rebase local commits to the new head of
upstream tree.'
-: ${GIT_DIR=.git}
+case "$#,$1" in
+1,*..*)
+ upstream=$(expr "$1" : '\(.*\)\.\.') ours=$(expr "$1" : '.*\.\.\(.*\)$')
+ set x "$upstream" "$ours"
+ shift ;;
+esac
case "$#" in
-1) linus=`git-rev-parse --verify "$1"` &&
- junio=`git-rev-parse --verify HEAD` || exit
+1) upstream=`git-rev-parse --verify "$1"` &&
+ ours=`git-rev-parse --verify HEAD` || exit
;;
-2) linus=`git-rev-parse --verify "$1"` &&
- junio=`git-rev-parse --verify "$2"` || exit
+2) upstream=`git-rev-parse --verify "$1"` &&
+ ours=`git-rev-parse --verify "$2"` || exit
;;
*) echo >&2 "$usage"; exit 1 ;;
esac
-git-read-tree -m -u $junio $linus &&
-echo "$linus" >"$GIT_DIR/HEAD" || exit
+git-read-tree -m -u $ours $upstream &&
+echo "$upstream" >"$GIT_DIR/HEAD" || exit
tmp=.rebase-tmp$$
fail=$tmp-fail
@@ -29,7 +36,7 @@ trap "rm -rf $tmp-*" 0 1 2 3 15
>$fail
-git-cherry $linus $junio |
+git-cherry $upstream $ours |
while read sign commit
do
case "$sign" in
@@ -37,7 +44,7 @@ do
esac
S=`cat "$GIT_DIR/HEAD"` &&
GIT_EXTERNAL_DIFF=git-apply-patch-script git-diff-tree -p $commit &&
- git-commit-script -m "$commit" || {
+ git-commit-script -C "$commit" || {
echo $commit >>$fail
git-read-tree --reset -u $S
}
diff --git a/git-reset-script b/git-reset-script
index b6476edc30..49994df7a2 100755
--- a/git-reset-script
+++ b/git-reset-script
@@ -2,6 +2,12 @@
. git-sh-setup-script || die "Not a git archive"
rev=$(git-rev-parse --revs-only --verify --default HEAD "$@") || exit
rev=$(git-rev-parse --revs-only --verify $rev^0) || exit
-git-read-tree --reset "$rev" && echo "$rev" > "$GIT_DIR/HEAD"
+git-read-tree --reset "$rev" && {
+ if orig=$(git-rev-parse --verify HEAD 2>/dev/null)
+ then
+ echo "$orig" >"$GIT_DIR/ORIG_HEAD"
+ fi
+ echo "$rev" > "$GIT_DIR/HEAD"
+}
git-update-cache --refresh
rm -f "$GIT_DIR/MERGE_HEAD"
diff --git a/git-revert-script b/git-revert-script
new file mode 100755
index 0000000000..dc2dea4898
--- /dev/null
+++ b/git-revert-script
@@ -0,0 +1,37 @@
+#!/bin/sh
+. git-sh-setup-script || die "Not a git archive"
+
+# We want a clean tree and clean index to be able to revert.
+status=$(git status)
+case "$status" in
+'nothing to commit') ;;
+*)
+ echo "$status"
+ die "Your working tree is dirty; cannot revert a previous patch." ;;
+esac
+
+rev=$(git-rev-parse --no-flags --verify --revs-only "$@") &&
+commit=$(git-rev-parse --verify "$rev^0") || exit
+if git-diff-tree -R -M -p $commit | git-apply --index &&
+ msg=$(git-rev-list --pretty=oneline --max-count=1 $commit)
+then
+ {
+ echo "$msg" | sed -e '
+ s/^[^ ]* /Revert "/
+ s/$/"/'
+ echo
+ echo "This reverts $commit commit."
+ test "$rev" = "$commit" ||
+ echo "(original 'git revert' arguments: $@)"
+ } | git commit -F -
+else
+ # Now why did it fail?
+ parents=`git-cat-file commit "$commit" 2>/dev/null |
+ sed -ne '/^$/q;/^parent /p' |
+ wc -l`
+ case $parents in
+ 0) die "Cannot revert the root commit nor non commit-ish." ;;
+ 1) die "The patch does not apply." ;;
+ *) die "Cannot revert a merge commit." ;;
+ esac
+fi
diff --git a/pack-check.c b/pack-check.c
index 054b0131e9..511f29424a 100644
--- a/pack-check.c
+++ b/pack-check.c
@@ -15,7 +15,7 @@ static int verify_packfile(struct packed_git *p)
/* Header consistency check */
hdr = p->pack_base;
if (hdr->hdr_signature != htonl(PACK_SIGNATURE))
- return error("Packfile signature mismatch", p->pack_name);
+ return error("Packfile %s signature mismatch", p->pack_name);
if (hdr->hdr_version != htonl(PACK_VERSION))
return error("Packfile version %d different from ours %d",
ntohl(hdr->hdr_version), PACK_VERSION);
diff --git a/pkt-line.h b/pkt-line.h
index b0b4f6d495..51d0cbe219 100644
--- a/pkt-line.h
+++ b/pkt-line.h
@@ -5,7 +5,7 @@
* Silly packetized line writing interface
*/
void packet_flush(int fd);
-void packet_write(int fd, const char *fmt, ...);
+void packet_write(int fd, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
int packet_read_line(int fd, char *buffer, unsigned size);
diff --git a/refs.c b/refs.c
index 774f1630fe..a5c8946610 100644
--- a/refs.c
+++ b/refs.c
@@ -6,7 +6,7 @@
static int read_ref(const char *refname, unsigned char *sha1)
{
int ret = -1;
- int fd = open(git_path(refname), O_RDONLY);
+ int fd = open(git_path("%s", refname), O_RDONLY);
if (fd >= 0) {
char buffer[60];
@@ -20,7 +20,7 @@ static int read_ref(const char *refname, unsigned char *sha1)
static int do_for_each_ref(const char *base, int (*fn)(const char *path, const unsigned char *sha1))
{
int retval = 0;
- DIR *dir = opendir(git_path(base));
+ DIR *dir = opendir(git_path("%s", base));
if (dir) {
struct dirent *de;
@@ -46,7 +46,7 @@ static int do_for_each_ref(const char *base, int (*fn)(const char *path, const u
if (namelen > 255)
continue;
memcpy(path + baselen, de->d_name, namelen+1);
- if (lstat(git_path(path), &st) < 0)
+ if (lstat(git_path("%s", path), &st) < 0)
continue;
if (S_ISDIR(st.st_mode)) {
retval = do_for_each_ref(path, fn);
diff --git a/rev-list.c b/rev-list.c
index fae30a2b68..ce5b8b2ad5 100644
--- a/rev-list.c
+++ b/rev-list.c
@@ -15,12 +15,15 @@ static const char rev_list_usage[] =
" --max-count=nr\n"
" --max-age=epoch\n"
" --min-age=epoch\n"
+ " --parents\n"
" --bisect\n"
" --objects\n"
" --unpacked\n"
" --header\n"
" --pretty\n"
- " --merge-order [ --show-breaks ]";
+ " --no-merges\n"
+ " --merge-order [ --show-breaks ]\n"
+ " --topo-order";
static int unpacked = 0;
static int bisect_list = 0;
@@ -39,6 +42,7 @@ static int merge_order = 0;
static int show_breaks = 0;
static int stop_traversal = 0;
static int topo_order = 0;
+static int no_merges = 0;
static void show_commit(struct commit *commit)
{
@@ -59,7 +63,11 @@ static void show_commit(struct commit *commit)
parents = parents->next;
}
}
- putchar('\n');
+ if (commit_format == CMIT_FMT_ONELINE)
+ putchar(' ');
+ else
+ putchar('\n');
+
if (verbose_header) {
static char pretty_header[16384];
pretty_print_commit(commit_format, commit->buffer, ~0, pretty_header, sizeof(pretty_header));
@@ -82,6 +90,8 @@ static int filter_commit(struct commit * commit)
}
if (max_count != -1 && !max_count--)
return STOP;
+ if (no_merges && (commit->parents && commit->parents->next))
+ return CONTINUE;
return DO;
}
@@ -497,7 +507,14 @@ int main(int argc, char **argv)
commit_format = get_commit_format(arg+8);
verbose_header = 1;
hdr_termination = '\n';
- prefix = "commit ";
+ if (commit_format == CMIT_FMT_ONELINE)
+ prefix = "";
+ else
+ prefix = "commit ";
+ continue;
+ }
+ if (!strncmp(arg, "--no-merges", 11)) {
+ no_merges = 1;
continue;
}
if (!strcmp(arg, "--parents")) {
diff --git a/rev-parse.c b/rev-parse.c
index 1965e90a8a..1c6ae76f9a 100644
--- a/rev-parse.c
+++ b/rev-parse.c
@@ -33,6 +33,9 @@ static int is_rev_argument(const char *arg)
"--max-age=",
"--min-age=",
"--merge-order",
+ "--topo-order",
+ "--bisect",
+ "--no-merges",
NULL
};
const char **p = rev_args;
diff --git a/rsh.c b/rsh.c
index fe87e581d2..bcb1c80d84 100644
--- a/rsh.c
+++ b/rsh.c
@@ -56,10 +56,16 @@ int setup_connection(int *fd_in, int *fd_out, const char *remote_prog,
return error("Couldn't create socket");
}
if (!fork()) {
+ const char *ssh = getenv("GIT_SSH") ? : "ssh";
+ const char *ssh_basename = strrchr(ssh, '/');
+ if (!ssh_basename)
+ ssh_basename = ssh;
+ else
+ ssh_basename++;
close(sv[1]);
dup2(sv[0], 0);
dup2(sv[0], 1);
- execlp("ssh", "ssh", host, command, NULL);
+ execlp(ssh, ssh_basename, host, command, NULL);
}
close(sv[0]);
*fd_in = sv[1];
diff --git a/sha1_file.c b/sha1_file.c
index e9285c144e..8d189d4919 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1388,7 +1388,7 @@ int write_sha1_from_fd(const unsigned char *sha1, int fd, char *buffer,
ssize_t size;
if (*bufposn) {
stream.avail_in = *bufposn;
- stream.next_in = buffer;
+ stream.next_in = (unsigned char *) buffer;
do {
stream.next_out = discard;
stream.avail_out = sizeof(discard);
diff --git a/tar-tree.c b/tar-tree.c
index a877fe545e..2716ae3eb1 100644
--- a/tar-tree.c
+++ b/tar-tree.c
@@ -325,8 +325,8 @@ static void write_header(const unsigned char *sha1, char typeflag, const char *b
memcpy(&header[257], "ustar", 6);
memcpy(&header[263], "00", 2);
- printf(&header[329], "%07o", 0); /* devmajor */
- printf(&header[337], "%07o", 0); /* devminor */
+ sprintf(&header[329], "%07o", 0); /* devmajor */
+ sprintf(&header[337], "%07o", 0); /* devminor */
memset(&header[148], ' ', 8);
for (i = 0; i < RECORDSIZE; i++)
diff --git a/tools/mailsplit.c b/tools/mailsplit.c
index 7b712081cb..a3238c20da 100644
--- a/tools/mailsplit.c
+++ b/tools/mailsplit.c
@@ -77,7 +77,7 @@ static int parse_email(const void *map, unsigned long size)
/*
* Search for a line beginning with "From ", and
- * having smething that looks like a date format.
+ * having something that looks like a date format.
*/
do {
int len = linelen(map, size);