summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/SubmittingPatches4
-rw-r--r--Documentation/git-quiltimport.txt61
-rwxr-xr-xDocumentation/install-webdoc.sh8
-rw-r--r--Makefile41
-rw-r--r--apply.c82
-rw-r--r--builtin-check-ref-format.c14
-rw-r--r--builtin-diff.c2
-rw-r--r--builtin-grep.c23
-rw-r--r--builtin-init-db.c (renamed from init-db.c)12
-rw-r--r--builtin-log.c7
-rw-r--r--builtin-rev-list.c (renamed from rev-list.c)5
-rw-r--r--builtin.h3
-rw-r--r--cache.h6
-rw-r--r--check-ref-format.c17
-rw-r--r--commit.c38
-rw-r--r--diff-tree.c5
-rwxr-xr-xgit-am.sh38
-rwxr-xr-xgit-cvsimport.perl2
-rwxr-xr-xgit-quiltimport.sh118
-rw-r--r--git.c3
-rw-r--r--read-cache.c117
-rw-r--r--refs.c5
-rw-r--r--update-index.c128
23 files changed, 494 insertions, 245 deletions
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index 318b04fdeb..8601949e80 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -266,8 +266,8 @@ This recipe appears to work with the current [*1*] Thunderbird from Suse.
The following Thunderbird extensions are needed:
AboutConfig 0.5
http://aboutconfig.mozdev.org/
- External Editor 0.5.4
- http://extensionroom.mozdev.org/more-info/exteditor
+ External Editor 0.7.2
+ http://globs.org/articles.php?lng=en&pg=8
1) Prepare the patch as a text file using your method of choice.
diff --git a/Documentation/git-quiltimport.txt b/Documentation/git-quiltimport.txt
new file mode 100644
index 0000000000..6e9a8c369a
--- /dev/null
+++ b/Documentation/git-quiltimport.txt
@@ -0,0 +1,61 @@
+git-quiltimport(1)
+================
+
+NAME
+----
+git-quiltimport - Applies a quilt patchset onto the current branch
+
+
+SYNOPSIS
+--------
+[verse]
+'git-quiltimport' [--dry-run] [--author <author>] [--patches <dir>]
+
+
+DESCRIPTION
+-----------
+Applies a quilt patchset onto the current git branch, preserving
+the patch boundaries, patch order, and patch descriptions present
+in the quilt patchset.
+
+For each patch the code attempts to extract the author from the
+patch description. If that fails it falls back to the author
+specified with --author. If the --author flag was not given
+the patch description is displayed and the user is asked to
+interactively enter the author of the patch.
+
+If a subject is not found in the patch description the patch name is
+preserved as the 1 line subject in the git description.
+
+OPTIONS
+-------
+--dry-run::
+ Walk through the patches in the series and warn
+ if we cannot find all of the necessary information to commit
+ a patch. At the time of this writing only missing author
+ information is warned about.
+
+--author Author Name <Author Email>::
+ The author name and email address to use when no author
+ information can be found in the patch description.
+
+--patches <dir>::
+ The directory to find the quilt patches and the
+ quilt series file.
+
+ The default for the patch directory is patches
+ or the value of the $QUILT_PATCHES environment
+ variable.
+
+Author
+------
+Written by Eric Biederman <ebiederm@lnxi.com>
+
+Documentation
+--------------
+Documentation by Eric Biederman <ebiederm@lnxi.com>
+
+GIT
+---
+Part of the gitlink:git[7] suite
+
diff --git a/Documentation/install-webdoc.sh b/Documentation/install-webdoc.sh
index 50638c78d5..60211a5058 100755
--- a/Documentation/install-webdoc.sh
+++ b/Documentation/install-webdoc.sh
@@ -4,12 +4,16 @@ T="$1"
for h in *.html *.txt howto/*.txt howto/*.html
do
- diff -u -I'Last updated [0-9][0-9]-[A-Z][a-z][a-z]-' "$T/$h" "$h" || {
+ if test -f "$T/$h" &&
+ diff -u -I'Last updated [0-9][0-9]-[A-Z][a-z][a-z]-' "$T/$h" "$h"
+ then
+ :; # up to date
+ else
echo >&2 "# install $h $T/$h"
rm -f "$T/$h"
mkdir -p `dirname "$T/$h"`
cp "$h" "$T/$h"
- }
+ fi
done
strip_leading=`echo "$T/" | sed -e 's|.|.|g'`
for th in "$T"/*.html "$T"/*.txt "$T"/howto/*.txt "$T"/howto/*.html
diff --git a/Makefile b/Makefile
index 9ba608c805..3a31ce0150 100644
--- a/Makefile
+++ b/Makefile
@@ -125,7 +125,7 @@ SCRIPT_SH = \
git-applymbox.sh git-applypatch.sh git-am.sh \
git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
git-merge-resolve.sh git-merge-ours.sh \
- git-lost-found.sh
+ git-lost-found.sh git-quiltimport.sh
SCRIPT_PERL = \
git-archimport.perl git-cvsimport.perl git-relink.perl \
@@ -154,23 +154,24 @@ PROGRAMS = \
git-convert-objects$X git-diff-files$X \
git-diff-index$X git-diff-stages$X \
git-diff-tree$X git-fetch-pack$X git-fsck-objects$X \
- git-hash-object$X git-index-pack$X git-init-db$X git-local-fetch$X \
+ git-hash-object$X git-index-pack$X git-local-fetch$X \
git-ls-files$X git-ls-tree$X git-mailinfo$X git-merge-base$X \
git-merge-index$X git-mktag$X git-mktree$X git-pack-objects$X git-patch-id$X \
git-peek-remote$X git-prune-packed$X git-read-tree$X \
- git-receive-pack$X git-rev-list$X git-rev-parse$X \
+ git-receive-pack$X git-rev-parse$X \
git-send-pack$X git-show-branch$X git-shell$X \
git-show-index$X git-ssh-fetch$X \
git-ssh-upload$X git-tar-tree$X git-unpack-file$X \
git-unpack-objects$X git-update-index$X git-update-server-info$X \
git-upload-pack$X git-verify-pack$X git-write-tree$X \
- git-update-ref$X git-symbolic-ref$X git-check-ref-format$X \
+ git-update-ref$X git-symbolic-ref$X \
git-name-rev$X git-pack-redundant$X git-repo-config$X git-var$X \
git-describe$X git-merge-tree$X git-blame$X git-imap-send$X
BUILT_INS = git-log$X git-whatchanged$X git-show$X \
git-count-objects$X git-diff$X git-push$X \
- git-grep$X
+ git-grep$X git-rev-list$X git-check-ref-format$X \
+ git-init-db$X
# what 'all' will build and 'install' will install, in gitexecdir
ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS)
@@ -218,7 +219,8 @@ LIB_OBJS = \
BUILTIN_OBJS = \
builtin-log.o builtin-help.o builtin-count.o builtin-diff.o builtin-push.o \
- builtin-grep.o
+ builtin-grep.o builtin-rev-list.o builtin-check-ref-format.o \
+ builtin-init-db.o
GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
LIBS = $(GITLIBS) -lz
@@ -473,6 +475,7 @@ strip: $(PROGRAMS) git$X
git$X: git.c common-cmds.h $(BUILTIN_OBJS) $(GITLIBS)
$(CC) -DGIT_VERSION='"$(GIT_VERSION)"' \
+ -DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"' \
$(ALL_CFLAGS) -o $@ $(filter %.c,$^) \
$(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
@@ -565,10 +568,6 @@ git-http-push$X: revision.o http.o http-push.o $(LIB_FILE)
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
-init-db.o: init-db.c
- $(CC) -c $(ALL_CFLAGS) \
- -DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"' $*.c
-
$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
$(patsubst git-%$X,%.o,$(PROGRAMS)): $(GITLIBS)
$(DIFF_OBJS): diffcore.h
@@ -652,6 +651,25 @@ dist: git.spec git-tar-tree
rpm: dist
$(RPMBUILD) -ta $(GIT_TARNAME).tar.gz
+htmldocs = git-htmldocs-$(GIT_VERSION)
+manpages = git-manpages-$(GIT_VERSION)
+dist-doc:
+ rm -fr .doc-tmp-dir
+ mkdir .doc-tmp-dir
+ $(MAKE) -C Documentation WEBDOC_DEST=../.doc-tmp-dir install-webdoc
+ cd .doc-tmp-dir && $(TAR) cf ../$(htmldocs).tar .
+ gzip -n -9 -f $(htmldocs).tar
+ :
+ rm -fr .doc-tmp-dir
+ mkdir .doc-tmp-dir .doc-tmp-dir/man1 .doc-tmp-dir/man7
+ $(MAKE) -C Documentation DESTDIR=. \
+ man1=../.doc-tmp-dir/man1 \
+ man7=../.doc-tmp-dir/man7 \
+ install
+ cd .doc-tmp-dir && $(TAR) cf ../$(manpages).tar .
+ gzip -n -9 -f $(manpages).tar
+ rm -fr .doc-tmp-dir
+
### Cleaning rules
clean:
@@ -659,8 +677,9 @@ clean:
$(LIB_FILE) $(XDIFF_LIB)
rm -f $(ALL_PROGRAMS) $(BUILT_INS) git$X
rm -f *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags
- rm -rf $(GIT_TARNAME)
+ rm -rf $(GIT_TARNAME) .doc-tmp-dir
rm -f $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz
+ rm -f $(htmldocs).tar $(manpages).tar
$(MAKE) -C Documentation/ clean
$(MAKE) -C templates clean
$(MAKE) -C t/ clean
diff --git a/apply.c b/apply.c
index 7c8146a7f3..0ed9d132e8 100644
--- a/apply.c
+++ b/apply.c
@@ -17,6 +17,8 @@
// --stat does just a diffstat, and doesn't actually apply
// --numstat does numeric diffstat, and doesn't actually apply
// --index-info shows the old and new index info for paths if available.
+// --index updates the cache as well.
+// --cached updates only the cache without ever touching the working tree.
//
static const char *prefix;
static int prefix_length = -1;
@@ -26,6 +28,7 @@ static int p_value = 1;
static int allow_binary_replacement = 0;
static int check_index = 0;
static int write_index = 0;
+static int cached = 0;
static int diffstat = 0;
static int numstat = 0;
static int summary = 0;
@@ -36,7 +39,7 @@ static int show_index_info = 0;
static int line_termination = '\n';
static unsigned long p_context = -1;
static const char apply_usage[] =
-"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [-z] [-pNUM] [-CNUM] [--whitespace=<nowarn|warn|error|error-all|strip>] <patch>...";
+"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--cached] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [-z] [-pNUM] [-CNUM] [--whitespace=<nowarn|warn|error|error-all|strip>] <patch>...";
static enum whitespace_eol {
nowarn_whitespace,
@@ -1600,7 +1603,7 @@ static int apply_fragments(struct buffer_desc *desc, struct patch *patch)
return 0;
}
-static int apply_data(struct patch *patch, struct stat *st)
+static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *ce)
{
char *buf;
unsigned long size, alloc;
@@ -1609,7 +1612,17 @@ static int apply_data(struct patch *patch, struct stat *st)
size = 0;
alloc = 0;
buf = NULL;
- if (patch->old_name) {
+ if (cached) {
+ if (ce) {
+ char type[20];
+ buf = read_sha1_file(ce->sha1, type, &size);
+ if (!buf)
+ return error("read of %s failed",
+ patch->old_name);
+ alloc = size;
+ }
+ }
+ else if (patch->old_name) {
size = st->st_size;
alloc = size + 8192;
buf = xmalloc(alloc);
@@ -1637,16 +1650,21 @@ static int check_patch(struct patch *patch)
const char *old_name = patch->old_name;
const char *new_name = patch->new_name;
const char *name = old_name ? old_name : new_name;
+ struct cache_entry *ce = NULL;
if (old_name) {
- int changed;
- int stat_ret = lstat(old_name, &st);
+ int changed = 0;
+ int stat_ret = 0;
+ unsigned st_mode = 0;
+ if (!cached)
+ stat_ret = lstat(old_name, &st);
if (check_index) {
int pos = cache_name_pos(old_name, strlen(old_name));
if (pos < 0)
return error("%s: does not exist in index",
old_name);
+ ce = active_cache[pos];
if (stat_ret < 0) {
struct checkout costate;
if (errno != ENOENT)
@@ -1659,40 +1677,46 @@ static int check_patch(struct patch *patch)
costate.quiet = 0;
costate.not_new = 0;
costate.refresh_cache = 1;
- if (checkout_entry(active_cache[pos],
+ if (checkout_entry(ce,
&costate,
NULL) ||
lstat(old_name, &st))
return -1;
}
-
- changed = ce_match_stat(active_cache[pos], &st, 1);
+ if (!cached)
+ changed = ce_match_stat(ce, &st, 1);
if (changed)
return error("%s: does not match index",
old_name);
+ if (cached)
+ st_mode = ntohl(ce->ce_mode);
}
else if (stat_ret < 0)
return error("%s: %s", old_name, strerror(errno));
+ if (!cached)
+ st_mode = ntohl(create_ce_mode(st.st_mode));
+
if (patch->is_new < 0)
patch->is_new = 0;
- st.st_mode = ntohl(create_ce_mode(st.st_mode));
if (!patch->old_mode)
- patch->old_mode = st.st_mode;
- if ((st.st_mode ^ patch->old_mode) & S_IFMT)
+ patch->old_mode = st_mode;
+ if ((st_mode ^ patch->old_mode) & S_IFMT)
return error("%s: wrong type", old_name);
- if (st.st_mode != patch->old_mode)
+ if (st_mode != patch->old_mode)
fprintf(stderr, "warning: %s has type %o, expected %o\n",
- old_name, st.st_mode, patch->old_mode);
+ old_name, st_mode, patch->old_mode);
}
if (new_name && (patch->is_new | patch->is_rename | patch->is_copy)) {
if (check_index && cache_name_pos(new_name, strlen(new_name)) >= 0)
return error("%s: already exists in index", new_name);
- if (!lstat(new_name, &st))
- return error("%s: already exists in working directory", new_name);
- if (errno != ENOENT)
- return error("%s: %s", new_name, strerror(errno));
+ if (!cached) {
+ if (!lstat(new_name, &st))
+ return error("%s: already exists in working directory", new_name);
+ if (errno != ENOENT)
+ return error("%s: %s", new_name, strerror(errno));
+ }
if (!patch->new_mode) {
if (patch->is_new)
patch->new_mode = S_IFREG | 0644;
@@ -1709,9 +1733,9 @@ static int check_patch(struct patch *patch)
return error("new mode (%o) of %s does not match old mode (%o)%s%s",
patch->new_mode, new_name, patch->old_mode,
same ? "" : " of ", same ? "" : old_name);
- }
+ }
- if (apply_data(patch, &st) < 0)
+ if (apply_data(patch, &st, ce) < 0)
return error("%s: patch does not apply", name);
return 0;
}
@@ -1778,7 +1802,7 @@ static void numstat_patch_list(struct patch *patch)
{
for ( ; patch; patch = patch->next) {
const char *name;
- name = patch->old_name ? patch->old_name : patch->new_name;
+ name = patch->new_name ? patch->new_name : patch->old_name;
printf("%d\t%d\t", patch->lines_added, patch->lines_deleted);
if (line_termination && quote_c_style(name, NULL, NULL, 0))
quote_c_style(name, NULL, stdout, 0);
@@ -1894,7 +1918,8 @@ static void remove_file(struct patch *patch)
if (remove_file_from_cache(patch->old_name) < 0)
die("unable to remove %s from index", patch->old_name);
}
- unlink(patch->old_name);
+ if (!cached)
+ unlink(patch->old_name);
}
static void add_index_file(const char *path, unsigned mode, void *buf, unsigned long size)
@@ -1911,9 +1936,11 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned
memcpy(ce->name, path, namelen);
ce->ce_mode = create_ce_mode(mode);
ce->ce_flags = htons(namelen);
- if (lstat(path, &st) < 0)
- die("unable to stat newly created file %s", path);
- fill_stat_cache_info(ce, &st);
+ if (!cached) {
+ if (lstat(path, &st) < 0)
+ die("unable to stat newly created file %s", path);
+ fill_stat_cache_info(ce, &st);
+ }
if (write_sha1_file(buf, size, blob_type, ce->sha1) < 0)
die("unable to create backing store for newly created file %s", path);
if (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD) < 0)
@@ -1950,6 +1977,8 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,
*/
static void create_one_file(char *path, unsigned mode, const char *buf, unsigned long size)
{
+ if (cached)
+ return;
if (!try_create_file(path, mode, buf, size))
return;
@@ -2182,6 +2211,11 @@ int main(int argc, char **argv)
check_index = 1;
continue;
}
+ if (!strcmp(arg, "--cached")) {
+ check_index = 1;
+ cached = 1;
+ continue;
+ }
if (!strcmp(arg, "--apply")) {
apply = 1;
continue;
diff --git a/builtin-check-ref-format.c b/builtin-check-ref-format.c
new file mode 100644
index 0000000000..4a23936aff
--- /dev/null
+++ b/builtin-check-ref-format.c
@@ -0,0 +1,14 @@
+/*
+ * GIT - The information manager from hell
+ */
+
+#include "cache.h"
+#include "refs.h"
+#include "builtin.h"
+
+int cmd_check_ref_format(int argc, const char **argv, char **envp)
+{
+ if (argc != 2)
+ usage("git check-ref-format refname");
+ return !!check_ref_format(argv[1]);
+}
diff --git a/builtin-diff.c b/builtin-diff.c
index b0c9cade02..de81b05e32 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -122,7 +122,7 @@ static int builtin_diff_b_f(struct rev_info *revs,
stuff_change(&revs->diffopt,
canon_mode(st.st_mode), canon_mode(st.st_mode),
blob[0].sha1, null_sha1,
- blob[0].name, path);
+ path, path);
diffcore_std(&revs->diffopt);
diff_flush(&revs->diffopt);
return 0;
diff --git a/builtin-grep.c b/builtin-grep.c
index 66111de514..d09ddf0485 100644
--- a/builtin-grep.c
+++ b/builtin-grep.c
@@ -453,7 +453,6 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
len = nr = 0;
push_arg("grep");
- push_arg("-H");
if (opt->fixed)
push_arg("-F");
if (opt->linenum)
@@ -503,17 +502,35 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
push_arg("-e");
push_arg(p->pattern);
}
- push_arg("--");
+
+ /*
+ * To make sure we get the header printed out when we want it,
+ * add /dev/null to the paths to grep. This is unnecessary
+ * (and wrong) with "-l" or "-L", which always print out the
+ * name anyway.
+ *
+ * GNU grep has "-H", but this is portable.
+ */
+ if (!opt->name_only && !opt->unmatch_name_only)
+ push_arg("/dev/null");
hit = 0;
argc = nr;
for (i = 0; i < active_nr; i++) {
struct cache_entry *ce = active_cache[i];
+ const char *name;
if (ce_stage(ce) || !S_ISREG(ntohl(ce->ce_mode)))
continue;
if (!pathspec_matches(paths, ce->name))
continue;
- argv[argc++] = ce->name;
+ name = ce->name;
+ if (name[0] == '-') {
+ int len = ce_namelen(ce);
+ name = xmalloc(len + 3);
+ memcpy(name, "./", 2);
+ memcpy(name + 2, ce->name, len + 1);
+ }
+ argv[argc++] = name;
if (argc < MAXARGS)
continue;
hit += exec_grep(argc, argv);
diff --git a/init-db.c b/builtin-init-db.c
index ff294960f2..2a1384ccb0 100644
--- a/init-db.c
+++ b/builtin-init-db.c
@@ -4,6 +4,7 @@
* Copyright (C) Linus Torvalds, 2005
*/
#include "cache.h"
+#include "builtin.h"
#ifndef DEFAULT_GIT_TEMPLATE_DIR
#define DEFAULT_GIT_TEMPLATE_DIR "/usr/share/git-core/templates/"
@@ -116,7 +117,7 @@ static void copy_templates_1(char *path, int baselen,
}
}
-static void copy_templates(const char *git_dir, int len, char *template_dir)
+static void copy_templates(const char *git_dir, int len, const char *template_dir)
{
char path[PATH_MAX];
char template_path[PATH_MAX];
@@ -163,7 +164,7 @@ static void copy_templates(const char *git_dir, int len, char *template_dir)
closedir(dir);
}
-static void create_default_files(const char *git_dir, char *template_path)
+static void create_default_files(const char *git_dir, const char *template_path)
{
unsigned len = strlen(git_dir);
static char path[PATH_MAX];
@@ -234,15 +235,16 @@ static const char init_db_usage[] =
* On the other hand, it might just make lookup slower and messier. You
* be the judge. The default case is to have one DB per managed directory.
*/
-int main(int argc, char **argv)
+int cmd_init_db(int argc, const char **argv, char **envp)
{
const char *git_dir;
const char *sha1_dir;
- char *path, *template_dir = NULL;
+ const char *template_dir = NULL;
+ char *path;
int len, i;
for (i = 1; i < argc; i++, argv++) {
- char *arg = argv[1];
+ const char *arg = argv[1];
if (!strncmp(arg, "--template=", 11))
template_dir = arg+11;
else if (!strcmp(arg, "--shared"))
diff --git a/builtin-log.c b/builtin-log.c
index 69f2911cb4..c4ceee0f98 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -19,6 +19,13 @@ static int cmd_log_wc(int argc, const char **argv, char **envp,
rev->commit_format = CMIT_FMT_DEFAULT;
rev->verbose_header = 1;
argc = setup_revisions(argc, argv, rev, "HEAD");
+ if (rev->always_show_header) {
+ if (rev->diffopt.pickaxe || rev->diffopt.filter) {
+ rev->always_show_header = 0;
+ if (rev->diffopt.output_format == DIFF_FORMAT_RAW)
+ rev->diffopt.output_format = DIFF_FORMAT_NO_OUTPUT;
+ }
+ }
if (argc > 1)
die("unrecognized argument: %s", argv[1]);
diff --git a/rev-list.c b/builtin-rev-list.c
index 8b0ec388fa..446802d377 100644
--- a/rev-list.c
+++ b/builtin-rev-list.c
@@ -7,6 +7,7 @@
#include "tree-walk.h"
#include "diff.h"
#include "revision.h"
+#include "builtin.h"
/* bits #0-15 in revision.h */
@@ -36,7 +37,7 @@ static const char rev_list_usage[] =
" --bisect"
;
-struct rev_info revs;
+static struct rev_info revs;
static int bisect_list = 0;
static int show_timestamp = 0;
@@ -291,7 +292,7 @@ static void mark_edges_uninteresting(struct commit_list *list)
}
}
-int main(int argc, const char **argv)
+int cmd_rev_list(int argc, const char **argv, char **envp)
{
struct commit_list *list;
int i;
diff --git a/builtin.h b/builtin.h
index 7744f7d2f6..60541262c4 100644
--- a/builtin.h
+++ b/builtin.h
@@ -24,5 +24,8 @@ extern int cmd_count_objects(int argc, const char **argv, char **envp);
extern int cmd_push(int argc, const char **argv, char **envp);
extern int cmd_grep(int argc, const char **argv, char **envp);
+extern int cmd_rev_list(int argc, const char **argv, char **envp);
+extern int cmd_check_ref_format(int argc, const char **argv, char **envp);
+extern int cmd_init_db(int argc, const char **argv, char **envp);
#endif
diff --git a/cache.h b/cache.h
index 4b7a439253..afa8e4f0ac 100644
--- a/cache.h
+++ b/cache.h
@@ -158,6 +158,12 @@ extern int index_pipe(unsigned char *sha1, int fd, const char *type, int write_o
extern int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object);
extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
+#define REFRESH_REALLY 0x0001 /* ignore_valid */
+#define REFRESH_UNMERGED 0x0002 /* allow unmerged */
+#define REFRESH_QUIET 0x0004 /* be quiet about it */
+#define REFRESH_IGNORE_MISSING 0x0008 /* ignore non-existent */
+extern int refresh_cache(unsigned int flags);
+
struct cache_file {
struct cache_file *next;
char lockfile[PATH_MAX];
diff --git a/check-ref-format.c b/check-ref-format.c
deleted file mode 100644
index a0adb3dcb3..0000000000
--- a/check-ref-format.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * GIT - The information manager from hell
- */
-
-#include "cache.h"
-#include "refs.h"
-
-#include <stdio.h>
-
-int main(int ac, char **av)
-{
- if (ac != 2)
- usage("git-check-ref-format refname");
- if (check_ref_format(av[1]))
- exit(1);
- return 0;
-}
diff --git a/commit.c b/commit.c
index 2717dd81c3..4a26070c13 100644
--- a/commit.c
+++ b/commit.c
@@ -22,23 +22,33 @@ struct sort_node
const char *commit_type = "commit";
+struct cmt_fmt_map {
+ const char *n;
+ size_t cmp_len;
+ enum cmit_fmt v;
+} cmt_fmts[] = {
+ { "raw", 1, CMIT_FMT_RAW },
+ { "medium", 1, CMIT_FMT_MEDIUM },
+ { "short", 1, CMIT_FMT_SHORT },
+ { "full", 5, CMIT_FMT_FULL },
+ { "fuller", 5, CMIT_FMT_FULLER },
+ { "oneline", 1, CMIT_FMT_ONELINE },
+};
+
enum cmit_fmt get_commit_format(const char *arg)
{
- if (!*arg)
+ int i;
+
+ if (!arg || !*arg)
return CMIT_FMT_DEFAULT;
- if (!strcmp(arg, "=raw"))
- return CMIT_FMT_RAW;
- if (!strcmp(arg, "=medium"))
- return CMIT_FMT_MEDIUM;
- if (!strcmp(arg, "=short"))
- return CMIT_FMT_SHORT;
- if (!strcmp(arg, "=full"))
- return CMIT_FMT_FULL;
- if (!strcmp(arg, "=fuller"))
- return CMIT_FMT_FULLER;
- if (!strcmp(arg, "=oneline"))
- return CMIT_FMT_ONELINE;
- die("invalid --pretty format");
+ if (*arg == '=')
+ arg++;
+ for (i = 0; i < ARRAY_SIZE(cmt_fmts); i++) {
+ if (!strncmp(arg, cmt_fmts[i].n, cmt_fmts[i].cmp_len))
+ return cmt_fmts[i].v;
+ }
+
+ die("invalid --pretty format: %s", arg);
}
static struct commit *check_commit(struct object *obj,
diff --git a/diff-tree.c b/diff-tree.c
index 7207867a74..69bb74b310 100644
--- a/diff-tree.c
+++ b/diff-tree.c
@@ -138,7 +138,10 @@ int main(int argc, const char **argv)
opt->diffopt.setup |= (DIFF_SETUP_USE_SIZE_CACHE |
DIFF_SETUP_USE_CACHE);
while (fgets(line, sizeof(line), stdin))
- diff_tree_stdin(line);
+ if (line[0] == '\n')
+ fflush(stdout);
+ else
+ diff_tree_stdin(line);
return 0;
}
diff --git a/git-am.sh b/git-am.sh
index 33f208cb0b..97ec2d0c7d 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -59,46 +59,12 @@ fall_back_3way () {
GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
git-write-tree >"$dotest/patch-merge-base+" &&
# index has the base tree now.
- (
- cd "$dotest/patch-merge-tmp-dir" &&
- GIT_INDEX_FILE="../patch-merge-tmp-index" \
- GIT_OBJECT_DIRECTORY="$O_OBJECT" \
- git-apply $binary --index <../patch
- )
+ GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
+ git-apply $binary --cached <"$dotest/patch"
then
echo Using index info to reconstruct a base tree...
mv "$dotest/patch-merge-base+" "$dotest/patch-merge-base"
mv "$dotest/patch-merge-tmp-index" "$dotest/patch-merge-index"
- else
- # Otherwise, try nearby trees that can be used to apply the
- # patch.
- (
- N=10
-
- # Hoping the patch is against our recent commits...
- git-rev-list --max-count=$N HEAD
-
- # or hoping the patch is against known tags...
- git-ls-remote --tags .
- ) |
- while read base junk
- do
- # See if we have it as a tree...
- git-cat-file tree "$base" >/dev/null 2>&1 || continue
-
- rm -fr "$dotest"/patch-merge-* &&
- mkdir "$dotest/patch-merge-tmp-dir" || break
- (
- cd "$dotest/patch-merge-tmp-dir" &&
- GIT_INDEX_FILE=../patch-merge-tmp-index &&
- GIT_OBJECT_DIRECTORY="$O_OBJECT" &&
- export GIT_INDEX_FILE GIT_OBJECT_DIRECTORY &&
- git-read-tree "$base" &&
- git-apply $binary --index &&
- mv ../patch-merge-tmp-index ../patch-merge-index &&
- echo "$base" >../patch-merge-base
- ) <"$dotest/patch" 2>/dev/null && break
- done
fi
test -f "$dotest/patch-merge-index" &&
diff --git a/git-cvsimport.perl b/git-cvsimport.perl
index c0ae00bda7..8c707f2c66 100755
--- a/git-cvsimport.perl
+++ b/git-cvsimport.perl
@@ -350,7 +350,7 @@ sub _line {
return $res;
} elsif($line =~ s/^E //) {
# print STDERR "S: $line\n";
- } elsif($line =~ /^Remove-entry /i) {
+ } elsif($line =~ /^(Remove-entry|Removed) /i) {
$line = $self->readline(); # filename
$line = $self->readline(); # OK
chomp $line;
diff --git a/git-quiltimport.sh b/git-quiltimport.sh
new file mode 100755
index 0000000000..12d9d0cbc9
--- /dev/null
+++ b/git-quiltimport.sh
@@ -0,0 +1,118 @@
+#!/bin/sh
+USAGE='--dry-run --author <author> --patches </path/to/quilt/patch/directory>'
+SUBDIRECTORY_ON=Yes
+. git-sh-setup
+
+dry_run=""
+quilt_author=""
+while case "$#" in 0) break;; esac
+do
+ case "$1" in
+ --au=*|--aut=*|--auth=*|--autho=*|--author=*)
+ quilt_author=$(expr "$1" : '-[^=]*\(.*\)')
+ shift
+ ;;
+
+ --au|--aut|--auth|--autho|--author)
+ case "$#" in 1) usage ;; esac
+ shift
+ quilt_author="$1"
+ shift
+ ;;
+
+ --dry-run)
+ shift
+ dry_run=1
+ ;;
+
+ --pa=*|--pat=*|--patc=*|--patch=*|--patche=*|--patches=*)
+ QUILT_PATCHES=$(expr "$1" : '-[^=]*\(.*\)')
+ shift
+ ;;
+
+ --pa|--pat|--patc|--patch|--patche|--patches)
+ case "$#" in 1) usage ;; esac
+ shift
+ QUILT_PATCHES="$1"
+ shift
+ ;;
+
+ *)
+ break
+ ;;
+ esac
+done
+
+# Quilt Author
+if [ -n "$quilt_author" ] ; then
+ quilt_author_name=$(expr "z$quilt_author" : 'z\(.*[^ ]\) *<.*') &&
+ quilt_author_email=$(expr "z$quilt_author" : '.*<\([^>]*\)') &&
+ test '' != "$quilt_author_name" &&
+ test '' != "$quilt_author_email" ||
+ die "malformatted --author parameter"
+fi
+
+# Quilt patch directory
+: ${QUILT_PATCHES:=patches}
+if ! [ -d "$QUILT_PATCHES" ] ; then
+ echo "The \"$QUILT_PATCHES\" directory does not exist."
+ exit 1
+fi
+
+# Temporay directories
+tmp_dir=.dotest
+tmp_msg="$tmp_dir/msg"
+tmp_patch="$tmp_dir/patch"
+tmp_info="$tmp_dir/info"
+
+
+# Find the intial commit
+commit=$(git-rev-parse HEAD)
+
+mkdir $tmp_dir || exit 2
+for patch_name in $(cat "$QUILT_PATCHES/series" | grep -v '^#'); do
+ echo $patch_name
+ (cat $QUILT_PATCHES/$patch_name | git-mailinfo "$tmp_msg" "$tmp_patch" > "$tmp_info") || exit 3
+
+ # Parse the author information
+ export GIT_AUTHOR_NAME=$(sed -ne 's/Author: //p' "$tmp_info")
+ export GIT_AUTHOR_EMAIL=$(sed -ne 's/Email: //p' "$tmp_info")
+ while test -z "$GIT_AUTHOR_EMAIL" && test -z "$GIT_AUTHOR_NAME" ; do
+ if [ -n "$quilt_author" ] ; then
+ GIT_AUTHOR_NAME="$quilt_author_name";
+ GIT_AUTHOR_EMAIL="$quilt_author_email";
+ elif [ -n "$dry_run" ]; then
+ echo "No author found in $patch_name" >&2;
+ GIT_AUTHOR_NAME="dry-run-not-found";
+ GIT_AUTHOR_EMAIL="dry-run-not-found";
+ else
+ echo "No author found in $patch_name" >&2;
+ echo "---"
+ cat $tmp_msg
+ echo -n "Author: ";
+ read patch_author
+
+ echo "$patch_author"
+
+ patch_author_name=$(expr "z$patch_author" : 'z\(.*[^ ]\) *<.*') &&
+ patch_author_email=$(expr "z$patch_author" : '.*<\([^>]*\)') &&
+ test '' != "$patch_author_name" &&
+ test '' != "$patch_author_email" &&
+ GIT_AUTHOR_NAME="$patch_author_name" &&
+ GIT_AUTHOR_EMAIL="$patch_author_email"
+ fi
+ done
+ export GIT_AUTHOR_DATE=$(sed -ne 's/Date: //p' "$tmp_info")
+ export SUBJECT=$(sed -ne 's/Subject: //p' "$tmp_info")
+ if [ -z "$SUBJECT" ] ; then
+ SUBJECT=$(echo $patch_name | sed -e 's/.patch$//')
+ fi
+
+ if [ -z "$dry_run" ] ; then
+ 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
+ fi
+done
+rm -rf $tmp_dir || exit 5
diff --git a/git.c b/git.c
index a94d9ee5a7..3216d311b2 100644
--- a/git.c
+++ b/git.c
@@ -50,6 +50,9 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
{ "count-objects", cmd_count_objects },
{ "diff", cmd_diff },
{ "grep", cmd_grep },
+ { "rev-list", cmd_rev_list },
+ { "init-db", cmd_init_db },
+ { "check-ref-format", cmd_check_ref_format }
};
int i;
diff --git a/read-cache.c b/read-cache.c
index a917ab0cfe..b95edcc14c 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -496,6 +496,123 @@ int add_cache_entry(struct cache_entry *ce, int option)
return 0;
}
+/* Three functions to allow overloaded pointer return; see linux/err.h */
+static inline void *ERR_PTR(long error)
+{
+ return (void *) error;
+}
+
+static inline long PTR_ERR(const void *ptr)
+{
+ return (long) ptr;
+}
+
+static inline long IS_ERR(const void *ptr)
+{
+ return (unsigned long)ptr > (unsigned long)-1000L;
+}
+
+/*
+ * "refresh" does not calculate a new sha1 file or bring the
+ * cache up-to-date for mode/content changes. But what it
+ * _does_ do is to "re-match" the stat information of a file
+ * with the cache, so that you can refresh the cache for a
+ * file that hasn't been changed but where the stat entry is
+ * out of date.
+ *
+ * For example, you'd want to do this after doing a "git-read-tree",
+ * to link up the stat cache details with the proper files.
+ */
+static struct cache_entry *refresh_entry(struct cache_entry *ce, int really)
+{
+ struct stat st;
+ struct cache_entry *updated;
+ int changed, size;
+
+ if (lstat(ce->name, &st) < 0)
+ return ERR_PTR(-errno);
+
+ changed = ce_match_stat(ce, &st, really);
+ if (!changed) {
+ if (really && assume_unchanged &&
+ !(ce->ce_flags & htons(CE_VALID)))
+ ; /* mark this one VALID again */
+ else
+ return NULL;
+ }
+
+ if (ce_modified(ce, &st, really))
+ return ERR_PTR(-EINVAL);
+
+ size = ce_size(ce);
+ updated = xmalloc(size);
+ memcpy(updated, ce, size);
+ fill_stat_cache_info(updated, &st);
+
+ /* In this case, if really is not set, we should leave
+ * CE_VALID bit alone. Otherwise, paths marked with
+ * --no-assume-unchanged (i.e. things to be edited) will
+ * reacquire CE_VALID bit automatically, which is not
+ * really what we want.
+ */
+ if (!really && assume_unchanged && !(ce->ce_flags & htons(CE_VALID)))
+ updated->ce_flags &= ~htons(CE_VALID);
+
+ return updated;
+}
+
+int refresh_cache(unsigned int flags)
+{
+ int i;
+ int has_errors = 0;
+ int really = (flags & REFRESH_REALLY) != 0;
+ int allow_unmerged = (flags & REFRESH_UNMERGED) != 0;
+ int quiet = (flags & REFRESH_QUIET) != 0;
+ int not_new = (flags & REFRESH_IGNORE_MISSING) != 0;
+
+ for (i = 0; i < active_nr; i++) {
+ struct cache_entry *ce, *new;
+ ce = active_cache[i];
+ if (ce_stage(ce)) {
+ while ((i < active_nr) &&
+ ! strcmp(active_cache[i]->name, ce->name))
+ i++;
+ i--;
+ if (allow_unmerged)
+ continue;
+ printf("%s: needs merge\n", ce->name);
+ has_errors = 1;
+ continue;
+ }
+
+ new = refresh_entry(ce, really);
+ if (!new)
+ continue;
+ if (IS_ERR(new)) {
+ if (not_new && PTR_ERR(new) == -ENOENT)
+ continue;
+ if (really && PTR_ERR(new) == -EINVAL) {
+ /* If we are doing --really-refresh that
+ * means the index is not valid anymore.
+ */
+ ce->ce_flags &= ~htons(CE_VALID);
+ active_cache_changed = 1;
+ }
+ if (quiet)
+ continue;
+ printf("%s: needs update\n", ce->name);
+ has_errors = 1;
+ continue;
+ }
+ active_cache_changed = 1;
+ /* You can NOT just free active_cache[i] here, since it
+ * might not be necessarily malloc()ed but can also come
+ * from mmap(). */
+ active_cache[i] = new;
+ }
+ return has_errors;
+}
+
static int verify_hdr(struct cache_header *hdr, unsigned long size)
{
SHA_CTX c;
diff --git a/refs.c b/refs.c
index 6c91ae6468..0f3491f871 100644
--- a/refs.c
+++ b/refs.c
@@ -220,12 +220,9 @@ static char *ref_lock_file_name(const char *ref)
int get_ref_sha1(const char *ref, unsigned char *sha1)
{
- const char *filename;
-
if (check_ref_format(ref))
return -1;
- filename = git_path("refs/%s", ref);
- return read_ref(filename, sha1);
+ return read_ref(git_path("refs/%s", ref), sha1);
}
static int lock_ref_file(const char *filename, const char *lock_filename,
diff --git a/update-index.c b/update-index.c
index 3d7e02db2c..7d6de821e2 100644
--- a/update-index.c
+++ b/update-index.c
@@ -18,9 +18,6 @@
static int allow_add;
static int allow_remove;
static int allow_replace;
-static int allow_unmerged; /* --refresh needing merge is not error */
-static int not_new; /* --refresh not having working tree files is not error */
-static int quiet; /* --refresh needing update is not error */
static int info_only;
static int force_remove;
static int verbose;
@@ -28,23 +25,6 @@ static int mark_valid_only = 0;
#define MARK_VALID 1
#define UNMARK_VALID 2
-
-/* Three functions to allow overloaded pointer return; see linux/err.h */
-static inline void *ERR_PTR(long error)
-{
- return (void *) error;
-}
-
-static inline long PTR_ERR(const void *ptr)
-{
- return (long) ptr;
-}
-
-static inline long IS_ERR(const void *ptr)
-{
- return (unsigned long)ptr > (unsigned long)-1000L;
-}
-
static void report(const char *fmt, ...)
{
va_list vp;
@@ -141,103 +121,6 @@ static int add_file_to_cache(const char *path)
}
/*
- * "refresh" does not calculate a new sha1 file or bring the
- * cache up-to-date for mode/content changes. But what it
- * _does_ do is to "re-match" the stat information of a file
- * with the cache, so that you can refresh the cache for a
- * file that hasn't been changed but where the stat entry is
- * out of date.
- *
- * For example, you'd want to do this after doing a "git-read-tree",
- * to link up the stat cache details with the proper files.
- */
-static struct cache_entry *refresh_entry(struct cache_entry *ce, int really)
-{
- struct stat st;
- struct cache_entry *updated;
- int changed, size;
-
- if (lstat(ce->name, &st) < 0)
- return ERR_PTR(-errno);
-
- changed = ce_match_stat(ce, &st, really);
- if (!changed) {
- if (really && assume_unchanged &&
- !(ce->ce_flags & htons(CE_VALID)))
- ; /* mark this one VALID again */
- else
- return NULL;
- }
-
- if (ce_modified(ce, &st, really))
- return ERR_PTR(-EINVAL);
-
- size = ce_size(ce);
- updated = xmalloc(size);
- memcpy(updated, ce, size);
- fill_stat_cache_info(updated, &st);
-
- /* In this case, if really is not set, we should leave
- * CE_VALID bit alone. Otherwise, paths marked with
- * --no-assume-unchanged (i.e. things to be edited) will
- * reacquire CE_VALID bit automatically, which is not
- * really what we want.
- */
- if (!really && assume_unchanged && !(ce->ce_flags & htons(CE_VALID)))
- updated->ce_flags &= ~htons(CE_VALID);
-
- return updated;
-}
-
-static int refresh_cache(int really)
-{
- int i;
- int has_errors = 0;
-
- for (i = 0; i < active_nr; i++) {
- struct cache_entry *ce, *new;
- ce = active_cache[i];
- if (ce_stage(ce)) {
- while ((i < active_nr) &&
- ! strcmp(active_cache[i]->name, ce->name))
- i++;
- i--;
- if (allow_unmerged)
- continue;
- printf("%s: needs merge\n", ce->name);
- has_errors = 1;
- continue;
- }
-
- new = refresh_entry(ce, really);
- if (!new)
- continue;
- if (IS_ERR(new)) {
- if (not_new && PTR_ERR(new) == -ENOENT)
- continue;
- if (really && PTR_ERR(new) == -EINVAL) {
- /* If we are doing --really-refresh that
- * means the index is not valid anymore.
- */
- ce->ce_flags &= ~htons(CE_VALID);
- active_cache_changed = 1;
- }
- if (quiet)
- continue;
- printf("%s: needs update\n", ce->name);
- has_errors = 1;
- continue;
- }
- active_cache_changed = 1;
- /* You can NOT just free active_cache[i] here, since it
- * might not be necessarily malloc()ed but can also come
- * from mmap(). */
- active_cache[i] = new;
- }
- return has_errors;
-}
-
-/*
* We fundamentally don't like some paths: we don't want
* dot or dot-dot anywhere, and for obvious reasons don't
* want to recurse into ".git" either.
@@ -653,6 +536,7 @@ int main(int argc, const char **argv)
const char *prefix = setup_git_directory();
int prefix_length = prefix ? strlen(prefix) : 0;
char set_executable_bit = 0;
+ unsigned int refresh_flags = 0;
git_config(git_default_config);
@@ -673,7 +557,7 @@ int main(int argc, const char **argv)
continue;
}
if (!strcmp(path, "-q")) {
- quiet = 1;
+ refresh_flags |= REFRESH_QUIET;
continue;
}
if (!strcmp(path, "--add")) {
@@ -689,15 +573,15 @@ int main(int argc, const char **argv)
continue;
}
if (!strcmp(path, "--unmerged")) {
- allow_unmerged = 1;
+ refresh_flags |= REFRESH_UNMERGED;
continue;
}
if (!strcmp(path, "--refresh")) {
- has_errors |= refresh_cache(0);
+ has_errors |= refresh_cache(refresh_flags);
continue;
}
if (!strcmp(path, "--really-refresh")) {
- has_errors |= refresh_cache(1);
+ has_errors |= refresh_cache(REFRESH_REALLY | refresh_flags);
continue;
}
if (!strcmp(path, "--cacheinfo")) {
@@ -770,7 +654,7 @@ int main(int argc, const char **argv)
goto finish;
}
if (!strcmp(path, "--ignore-missing")) {
- not_new = 1;
+ refresh_flags |= REFRESH_IGNORE_MISSING;
continue;
}
if (!strcmp(path, "--verbose")) {