aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Documentation/Makefile3
-rw-r--r--Documentation/RelNotes-1.5.2.2.txt61
-rw-r--r--Documentation/asciidoc.conf3
-rw-r--r--Documentation/git-blame.txt7
-rw-r--r--Documentation/git-cvsexportcommit.txt2
-rw-r--r--Documentation/git-cvsimport.txt23
-rw-r--r--Documentation/user-manual.txt4
-rw-r--r--Makefile21
-rw-r--r--builtin-blame.c16
-rw-r--r--builtin-revert.c4
-rw-r--r--cache.h16
-rw-r--r--commit.c2
-rw-r--r--compat/hstrerror.c21
-rw-r--r--config.c2
-rwxr-xr-xcontrib/gitview/gitview21
-rw-r--r--csum-file.c55
-rw-r--r--csum-file.h2
-rw-r--r--dir.c21
-rwxr-xr-xgenerate-cmdlist.sh2
-rw-r--r--git-compat-util.h5
-rwxr-xr-xgit-cvsimport.perl64
-rwxr-xr-xgit-remote.perl1
-rwxr-xr-xgit-svn.perl82
-rwxr-xr-xgitweb/gitweb.perl4
-rw-r--r--merge-recursive.c2
-rw-r--r--refs.c2
-rw-r--r--remote.c7
-rw-r--r--revision.c3
-rw-r--r--sha1_file.c4
-rwxr-xr-xt/t9113-git-svn-dcommit-new-file.sh40
31 files changed, 322 insertions, 180 deletions
diff --git a/.gitignore b/.gitignore
index bd49cd462..e8b060cbe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -157,7 +157,7 @@ common-cmds.h
*.tar.gz
*.dsc
*.deb
-git-core.spec
+git.spec
*.exe
*.[aos]
*.py[co]
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 2ad18e0ac..cc563247a 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -37,6 +37,9 @@ man7dir=$(mandir)/man7
ASCIIDOC=asciidoc
ASCIIDOC_EXTRA =
+ifdef ASCIIDOC8
+ASCIIDOC_EXTRA += -a asciidoc7compatible
+endif
INSTALL?=install
DOC_REF = origin/man
diff --git a/Documentation/RelNotes-1.5.2.2.txt b/Documentation/RelNotes-1.5.2.2.txt
new file mode 100644
index 000000000..f6393f8a9
--- /dev/null
+++ b/Documentation/RelNotes-1.5.2.2.txt
@@ -0,0 +1,61 @@
+GIT v1.5.2.2 Release Notes
+==========================
+
+Fixes since v1.5.2.1
+--------------------
+
+* Usability fix
+
+ - git-gui is shipped with its updated blame interface. It is
+ rumored that the older one was not just unusable but was
+ active health hazard, but this one is actually pretty.
+ Please see for yourself.
+
+* Bugfixes
+
+ - "git checkout fubar" was utterly confused when there is a
+ branch fubar and a tag fubar at the same time. It correctly
+ checks out the branch fubar now.
+
+ - "git clone /path/foo" to clone a local /path/foo.git
+ repository left an incorrect configuration.
+
+ - "git send-email" correctly unquotes RFC 2047 quoted names in
+ the patch-email before using their values.
+
+ - We did not accept number of seconds since epoch older than
+ year 2000 as a valid timestamp. We now interpret positive
+ integers more than 8 digits as such, which allows us to
+ express timestamps more recent than March 1973.
+
+ - git-cvsimport did not work when you have GIT_DIR to point
+ your repository at a nonstandard location.
+
+ - Some systems (notably, Solaris) lack hstrerror() to make
+ h_errno human readable; prepare a replacement
+ implementation.
+
+ - .gitignore file listed git-core.spec but what we generate is
+ git.spec, and nobody noticed for a long time.
+
+ - "git-merge-recursive" does not try to run file level merge
+ on binary files.
+
+ - "git-branch --track" did not create tracking configuration
+ correctly when the branch name had slash in it.
+
+ - The email address of the user specified with user.email
+ configuration was overriden by EMAIL environment variable.
+
+ - The tree parser did not warn about tree entries with
+ nonsense file modes, and assumed they must be blobs.
+
+ - "git log -z" without any other request to generate diff still
+ invoked the diff machinery, wasting cycles.
+
+* Documentation
+
+ - Many updates to fix stale or missing documentation.
+
+ - Although our documentation was primarily meant to be formatted
+ with AsciiDoc7, formatting with AsciiDoc8 is supported better.
diff --git a/Documentation/asciidoc.conf b/Documentation/asciidoc.conf
index 99302c5be..6b6220dfd 100644
--- a/Documentation/asciidoc.conf
+++ b/Documentation/asciidoc.conf
@@ -8,7 +8,8 @@
# the command.
[attributes]
-caret=^
+plus=+
+caret=^
startsb=[
endsb=]
tilde=~
diff --git a/Documentation/git-blame.txt b/Documentation/git-blame.txt
index 44678b0c3..66f120370 100644
--- a/Documentation/git-blame.txt
+++ b/Documentation/git-blame.txt
@@ -8,7 +8,7 @@ git-blame - Show what revision and author last modified each line of a file
SYNOPSIS
--------
[verse]
-'git-blame' [-c] [-b] [--root] [-s] [-l] [-t] [-f] [-n] [-p] [--incremental] [-L n,m]
+'git-blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-p] [-w] [--incremental] [-L n,m]
[-S <revs-file>] [-M] [-C] [-C] [--since=<date>]
[<rev> | --contents <file>] [--] <file>
@@ -63,6 +63,11 @@ include::blame-options.txt[]
-s::
Suppress author name and timestamp from the output.
+-w::
+ Ignore whitespace when comparing parent's version and
+ child's to find where the lines came from.
+
+
THE PORCELAIN FORMAT
--------------------
diff --git a/Documentation/git-cvsexportcommit.txt b/Documentation/git-cvsexportcommit.txt
index 827711c3c..6c423e3a2 100644
--- a/Documentation/git-cvsexportcommit.txt
+++ b/Documentation/git-cvsexportcommit.txt
@@ -76,7 +76,7 @@ $ git-cvsexportcommit -v <commit-sha1>
$ cvs commit -F .mgs <files>
------------
-Merge pending patches into CVS automatically -- only if you really know what you are doing ::
+Merge pending patches into CVS automatically -- only if you really know what you are doing::
+
------------
$ export GIT_DIR=~/project/.git
diff --git a/Documentation/git-cvsimport.txt b/Documentation/git-cvsimport.txt
index 3985e0164..fdd7ec7ed 100644
--- a/Documentation/git-cvsimport.txt
+++ b/Documentation/git-cvsimport.txt
@@ -13,7 +13,7 @@ SYNOPSIS
[-A <author-conv-file>] [-p <options-for-cvsps>] [-P <file>]
[-C <git_repository>] [-z <fuzz>] [-i] [-k] [-u] [-s <subst>]
[-a] [-m] [-M <regex>] [-S <regex>] [-L <commitlimit>]
- [<CVS_module>]
+ [-r <remote>] [<CVS_module>]
DESCRIPTION
@@ -25,10 +25,12 @@ Splitting the CVS log into patch sets is done by 'cvsps'.
At least version 2.1 is required.
You should *never* do any work of your own on the branches that are
-created by git-cvsimport. The initial import will create and populate a
+created by git-cvsimport. By default initial import will create and populate a
"master" branch from the CVS repository's main branch which you're free
to work with; after that, you need to 'git merge' incremental imports, or
-any CVS branches, yourself.
+any CVS branches, yourself. It is advisable to specify a named remote via
+-r to separate and protect the incoming branches.
+
OPTIONS
-------
@@ -51,10 +53,19 @@ OPTIONS
The git repository to import to. If the directory doesn't
exist, it will be created. Default is the current directory.
+-r <remote>::
+ The git remote to import this CVS repository into.
+ Moves all CVS branches into remotes/<remote>/<branch>
+ akin to the git-clone --use-separate-remote option.
+
-o <branch-for-HEAD>::
- The 'HEAD' branch from CVS is imported to the 'origin' branch within
- the git repository, as 'HEAD' already has a special meaning for git.
- Use this option if you want to import into a different branch.
+ When no remote is specified (via -r) the 'HEAD' branch
+ from CVS is imported to the 'origin' branch within the git
+ repository, as 'HEAD' already has a special meaning for git.
+ When a remote is specified the 'HEAD' branch is named
+ remotes/<remote>/master mirroring git-clone behaviour.
+ Use this option if you want to import into a different
+ branch.
+
Use '-o master' for continuing an import that was initially done by
the old cvs2git tool.
diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt
index 0bfa21b3d..ff7c71d4f 100644
--- a/Documentation/user-manual.txt
+++ b/Documentation/user-manual.txt
@@ -2757,8 +2757,8 @@ As a result, the general consistency of an object can always be tested
independently of the contents or the type of the object: all objects can
be validated by verifying that (a) their hashes match the content of the
file and (b) the object successfully inflates to a stream of bytes that
-forms a sequence of <ascii type without space> + <space> + <ascii decimal
-size> + <byte\0> + <binary object data>.
+forms a sequence of <ascii type without space> {plus} <space> {plus} <ascii decimal
+size> {plus} <byte\0> {plus} <binary object data>.
The structured objects can further have their structure and
connectivity to other objects verified. This is generally done with
diff --git a/Makefile b/Makefile
index 0f6540c6d..c09dfaf3f 100644
--- a/Makefile
+++ b/Makefile
@@ -107,6 +107,8 @@ all::
# Define USE_STDEV below if you want git to care about the underlying device
# change being considered an inode change from the update-cache perspective.
#
+# Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8
+#
# Define NO_PERL_MAKEMAKER if you cannot use Makefiles generated by perl's
# MakeMaker (e.g. using ActiveState under Cygwin).
#
@@ -410,6 +412,7 @@ ifeq ($(uname_S),SunOS)
NEEDS_NSL = YesPlease
SHELL_PATH = /bin/bash
NO_STRCASESTR = YesPlease
+ NO_HSTRERROR = YesPlease
ifeq ($(uname_R),5.8)
NEEDS_LIBICONV = YesPlease
NO_UNSETENV = YesPlease
@@ -654,6 +657,10 @@ endif
ifdef NO_PERL_MAKEMAKER
export NO_PERL_MAKEMAKER
endif
+ifdef NO_HSTRERROR
+ COMPAT_CFLAGS += -DNO_HSTRERROR
+ COMPAT_OBJS += compat/hstrerror.o
+endif
ifeq ($(TCLTK_PATH),)
NO_TCLTK=NoThanks
@@ -684,6 +691,10 @@ ifndef V
endif
endif
+ifdef ASCIIDOC8
+ export ASCIIDOC8
+endif
+
# Shell quote (do not use $(call) to accommodate ancient setups);
SHA1_HEADER_SQ = $(subst ','\'',$(SHA1_HEADER))
@@ -735,9 +746,13 @@ gitk-wish: gitk GIT-GUI-VARS
chmod +x $@+ && \
mv -f $@+ $@
-git$X: git.c common-cmds.h $(BUILTIN_OBJS) $(GITLIBS) GIT-CFLAGS
+git.o: git.c common-cmds.h GIT-CFLAGS
+ $(QUIET_CC)$(CC) -DGIT_VERSION='"$(GIT_VERSION)"' \
+ $(ALL_CFLAGS) -c $(filter %.c,$^)
+
+git$X: git.o $(BUILTIN_OBJS) $(GITLIBS)
$(QUIET_LINK)$(CC) -DGIT_VERSION='"$(GIT_VERSION)"' \
- $(ALL_CFLAGS) -o $@ $(filter %.c,$^) \
+ $(ALL_CFLAGS) -o $@ $(filter %.c,$^) git.o \
$(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
help.o: common-cmds.h
@@ -748,6 +763,8 @@ git-merge-subtree$X: git-merge-recursive$X
$(BUILT_INS): git$X
$(QUIET_BUILT_IN)rm -f $@ && ln git$X $@
+common-cmds.h: ./generate-cmdlist.sh
+
common-cmds.h: $(wildcard Documentation/git-*.txt)
$(QUIET_GEN)./generate-cmdlist.sh > $@+ && mv $@+ $@
diff --git a/builtin-blame.c b/builtin-blame.c
index 35471fc26..f7e2c1388 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -20,7 +20,7 @@
#include "mailmap.h"
static char blame_usage[] =
-"git-blame [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-p] [-L n,m] [-S <revs-file>] [-M] [-C] [-C] [--contents <filename>] [--incremental] [commit] [--] file\n"
+"git-blame [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-p] [-w] [-L n,m] [-S <revs-file>] [-M] [-C] [-C] [--contents <filename>] [--incremental] [commit] [--] file\n"
" -c Use the same output mode as git-annotate (Default: off)\n"
" -b Show blank SHA-1 for boundary commits (Default: off)\n"
" -l Show long commit SHA1 (Default: off)\n"
@@ -30,6 +30,7 @@ static char blame_usage[] =
" -n, --show-number Show original linenumber (Default: off)\n"
" -s Suppress author name and timestamp (Default: off)\n"
" -p, --porcelain Show in a format designed for machine consumption\n"
+" -w Ignore whitespace differences\n"
" -L n,m Process only line range n,m, counting from 1\n"
" -M, -C Find line movements within and across files\n"
" --incremental Show blame entries as we find them, incrementally\n"
@@ -45,6 +46,7 @@ static int show_root;
static int blank_boundary;
static int incremental;
static int cmd_is_annotate;
+static int xdl_opts = XDF_NEED_MINIMAL;
static struct path_list mailmap;
#ifndef DEBUG
@@ -515,7 +517,7 @@ static struct patch *compare_buffer(mmfile_t *file_p, mmfile_t *file_o,
xdemitconf_t xecfg;
xdemitcb_t ecb;
- xpp.flags = XDF_NEED_MINIMAL;
+ xpp.flags = xdl_opts;
xecfg.ctxlen = context;
xecfg.flags = 0;
ecb.outf = xdiff_outf;
@@ -1744,11 +1746,11 @@ static int read_ancestry(const char *graft_file)
*/
static int lineno_width(int lines)
{
- int i, width;
+ int i, width;
- for (width = 1, i = 10; i <= lines + 1; width++)
- i *= 10;
- return width;
+ for (width = 1, i = 10; i <= lines + 1; width++)
+ i *= 10;
+ return width;
}
/*
@@ -2159,6 +2161,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
output_option |= OUTPUT_LONG_OBJECT_NAME;
else if (!strcmp("-s", arg))
output_option |= OUTPUT_NO_AUTHOR;
+ else if (!strcmp("-w", arg))
+ xdl_opts |= XDF_IGNORE_WHITESPACE;
else if (!strcmp("-S", arg) && ++i < argc)
revs_file = argv[i];
else if (!prefixcmp(arg, "-M")) {
diff --git a/builtin-revert.c b/builtin-revert.c
index 8f02ed7bd..499bbe734 100644
--- a/builtin-revert.c
+++ b/builtin-revert.c
@@ -25,7 +25,7 @@ static const char *cherry_pick_usage = "git-cherry-pick [--edit] [-n] [-r] [-x]
static int edit;
static int replay;
-enum { REVERT, CHERRY_PICK } action;
+static enum { REVERT, CHERRY_PICK } action;
static int no_commit;
static struct commit *commit;
static int needed_deref;
@@ -129,7 +129,7 @@ static char *get_encoding(const char *message)
return NULL;
}
-struct lock_file msg_file;
+static struct lock_file msg_file;
static int msg_fd;
static void add_to_msg(const char *string)
diff --git a/cache.h b/cache.h
index 5e7381eb1..cec19ba44 100644
--- a/cache.h
+++ b/cache.h
@@ -225,6 +225,21 @@ extern void verify_non_filename(const char *prefix, const char *name);
#define alloc_nr(x) (((x)+16)*3/2)
+/*
+ * Realloc the buffer pointed at by variable 'x' so that it can hold
+ * at least 'nr' entries; the number of entries currently allocated
+ * is 'alloc', using the standard growing factor alloc_nr() macro.
+ *
+ * DO NOT USE any expression with side-effect for 'x' or 'alloc'.
+ */
+#define ALLOC_GROW(x, nr, alloc) \
+ do { \
+ if ((nr) >= alloc) { \
+ alloc = alloc_nr(alloc); \
+ x = xrealloc((x), alloc * sizeof(*(x))); \
+ } \
+ } while(0)
+
/* Initialize and use the cache information */
extern int read_index(struct index_state *);
extern int read_index_from(struct index_state *, const char *path);
@@ -354,7 +369,6 @@ extern int move_temp_to_file(const char *tmpfile, const char *filename);
extern int has_sha1_pack(const unsigned char *sha1, const char **ignore);
extern int has_sha1_file(const unsigned char *sha1);
-extern void *map_sha1_file(const unsigned char *sha1, unsigned long *);
extern int has_pack_file(const unsigned char *sha1);
extern int has_pack_index(const unsigned char *sha1);
diff --git a/commit.c b/commit.c
index 4ca4d44ba..54abdd798 100644
--- a/commit.c
+++ b/commit.c
@@ -27,7 +27,7 @@ struct sort_node
const char *commit_type = "commit";
-struct cmt_fmt_map {
+static struct cmt_fmt_map {
const char *n;
size_t cmp_len;
enum cmit_fmt v;
diff --git a/compat/hstrerror.c b/compat/hstrerror.c
new file mode 100644
index 000000000..069c555da
--- /dev/null
+++ b/compat/hstrerror.c
@@ -0,0 +1,21 @@
+#include <string.h>
+#include <stdio.h>
+#include <netdb.h>
+
+const char *githstrerror(int err)
+{
+ static char buffer[48];
+ switch (err)
+ {
+ case HOST_NOT_FOUND:
+ return "Authoritative answer: host not found";
+ case NO_DATA:
+ return "Valid name, no data record of requested type";
+ case NO_RECOVERY:
+ return "Non recoverable errors, FORMERR, REFUSED, NOTIMP";
+ case TRY_AGAIN:
+ return "Non-authoritative \"host not found\", or SERVERFAIL";
+ }
+ sprintf(buffer, "Name resolution error %d", err);
+ return buffer;
+}
diff --git a/config.c b/config.c
index 58d3ed5d3..e323153ae 100644
--- a/config.c
+++ b/config.c
@@ -523,7 +523,7 @@ static int store_aux(const char* key, const char* value)
return 0;
}
-static int write_error()
+static int write_error(void)
{
fprintf(stderr, "Failed to write new configuration file\n");
diff --git a/contrib/gitview/gitview b/contrib/gitview/gitview
index 098cb0135..593176662 100755
--- a/contrib/gitview/gitview
+++ b/contrib/gitview/gitview
@@ -352,6 +352,7 @@ class AnnotateWindow(object):
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.set_border_width(0)
self.window.set_title("Git repository browser annotation window")
+ self.prev_read = ""
# Use two thirds of the screen by default
screen = self.window.get_screen()
@@ -401,7 +402,10 @@ class AnnotateWindow(object):
def data_ready(self, source, condition):
while (1):
try :
- buffer = source.read(8192)
+ # A simple readline doesn't work
+ # a readline bug ??
+ buffer = source.read(100)
+
except:
# resource temporary not available
return True
@@ -411,6 +415,19 @@ class AnnotateWindow(object):
source.close()
return False
+ if (self.prev_read != ""):
+ buffer = self.prev_read + buffer
+ self.prev_read = ""
+
+ if (buffer[len(buffer) -1] != '\n'):
+ try:
+ newline_index = buffer.rindex("\n")
+ except ValueError:
+ newline_index = 0
+
+ self.prev_read = buffer[newline_index:(len(buffer))]
+ buffer = buffer[0:newline_index]
+
for buff in buffer.split("\n"):
annotate_line = re.compile('^([0-9a-f]{40}) (.+) (.+) (.+)$')
m = annotate_line.match(buff)
@@ -516,7 +533,7 @@ class AnnotateWindow(object):
self.add_file_data(filename, commit_sha1, line_num)
- fp = os.popen("git blame --incremental -- " + filename + " " + commit_sha1)
+ fp = os.popen("git blame --incremental -C -C -- " + filename + " " + commit_sha1)
flags = fcntl.fcntl(fp.fileno(), fcntl.F_GETFL)
fcntl.fcntl(fp.fileno(), fcntl.F_SETFL, flags | os.O_NONBLOCK)
self.io_watch_tag = gobject.io_add_watch(fp, gobject.IO_IN, self.data_ready)
diff --git a/csum-file.c b/csum-file.c
index 510934262..9ab997120 100644
--- a/csum-file.c
+++ b/csum-file.c
@@ -73,33 +73,6 @@ int sha1write(struct sha1file *f, void *buf, unsigned int count)
return 0;
}
-struct sha1file *sha1create(const char *fmt, ...)
-{
- struct sha1file *f;
- unsigned len;
- va_list arg;
- int fd;
-
- f = xmalloc(sizeof(*f));
-
- va_start(arg, fmt);
- len = vsnprintf(f->name, sizeof(f->name), fmt, arg);
- va_end(arg);
- if (len >= PATH_MAX)
- die("you wascally wabbit, you");
- f->namelen = len;
-
- fd = open(f->name, O_CREAT | O_EXCL | O_WRONLY, 0666);
- if (fd < 0)
- die("unable to open %s (%s)", f->name, strerror(errno));
- f->fd = fd;
- f->error = 0;
- f->offset = 0;
- f->do_crc = 0;
- SHA1_Init(&f->ctx);
- return f;
-}
-
struct sha1file *sha1fd(int fd, const char *name)
{
struct sha1file *f;
@@ -121,34 +94,6 @@ struct sha1file *sha1fd(int fd, const char *name)
return f;
}
-int sha1write_compressed(struct sha1file *f, void *in, unsigned int size, int level)
-{
- z_stream stream;
- unsigned long maxsize;
- void *out;
-
- memset(&stream, 0, sizeof(stream));
- deflateInit(&stream, level);
- maxsize = deflateBound(&stream, size);
- out = xmalloc(maxsize);
-
- /* Compress it */
- stream.next_in = in;
- stream.avail_in = size;
-
- stream.next_out = out;
- stream.avail_out = maxsize;
-
- while (deflate(&stream, Z_FINISH) == Z_OK)
- /* nothing */;
- deflateEnd(&stream);
-
- size = stream.total_out;
- sha1write(f, out, size);
- free(out);
- return size;
-}
-
void crc32_begin(struct sha1file *f)
{
f->crc32 = crc32(0, Z_NULL, 0);
diff --git a/csum-file.h b/csum-file.h
index 4e8b83e09..c3c792f1b 100644
--- a/csum-file.h
+++ b/csum-file.h
@@ -13,10 +13,8 @@ struct sha1file {
};
extern struct sha1file *sha1fd(int fd, const char *name);
-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, int);
extern void crc32_begin(struct sha1file *);
extern uint32_t crc32_end(struct sha1file *);
diff --git a/dir.c b/dir.c
index f543f50f4..5ba6030e9 100644
--- a/dir.c
+++ b/dir.c
@@ -271,27 +271,26 @@ int excluded(struct dir_struct *dir, const char *pathname)
return 0;
}
-struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathname, int len)
-{
+static struct dir_entry *dir_entry_new(const char *pathname, int len) {
struct dir_entry *ent;
- if (cache_name_pos(pathname, len) >= 0)
- return NULL;
-
- if (dir->nr == dir->alloc) {
- int alloc = alloc_nr(dir->alloc);
- dir->alloc = alloc;
- dir->entries = xrealloc(dir->entries, alloc*sizeof(ent));
- }
ent = xmalloc(sizeof(*ent) + len + 1);
ent->ignored = ent->ignored_dir = 0;
ent->len = len;
memcpy(ent->name, pathname, len);
ent->name[len] = 0;
- dir->entries[dir->nr++] = ent;
return ent;
}
+struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathname, int len)
+{
+ if (cache_name_pos(pathname, len) >= 0)
+ return NULL;
+
+ ALLOC_GROW(dir->entries, dir->nr, dir->alloc);
+ return dir->entries[dir->nr++] = dir_entry_new(pathname, len);
+}
+
enum exist_status {
index_nonexistent = 0,
index_directory,
diff --git a/generate-cmdlist.sh b/generate-cmdlist.sh
index 975777f05..17df47b95 100755
--- a/generate-cmdlist.sh
+++ b/generate-cmdlist.sh
@@ -7,7 +7,7 @@ struct cmdname_help
char help[80];
};
-struct cmdname_help common_cmds[] = {"
+static struct cmdname_help common_cmds[] = {"
sort <<\EOF |
add
diff --git a/git-compat-util.h b/git-compat-util.h
index 6bd8987b2..b2ab3f825 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -167,6 +167,11 @@ extern size_t gitstrlcpy(char *, const char *, size_t);
extern uintmax_t gitstrtoumax(const char *, char **, int);
#endif
+#ifdef NO_HSTRERROR
+#define hstrerror githstrerror
+extern const char *githstrerror(int herror);
+#endif
+
extern void release_pack_memory(size_t, int);
static inline char* xstrdup(const char *str)
diff --git a/git-cvsimport.perl b/git-cvsimport.perl
index 3225a2a25..433b7fd32 100755
--- a/git-cvsimport.perl
+++ b/git-cvsimport.perl
@@ -29,7 +29,7 @@ use IPC::Open2;
$SIG{'PIPE'}="IGNORE";
$ENV{'TZ'}="UTC";
-our ($opt_h,$opt_o,$opt_v,$opt_k,$opt_u,$opt_d,$opt_p,$opt_C,$opt_z,$opt_i,$opt_P, $opt_s,$opt_m,$opt_M,$opt_A,$opt_S,$opt_L, $opt_a);
+our ($opt_h,$opt_o,$opt_v,$opt_k,$opt_u,$opt_d,$opt_p,$opt_C,$opt_z,$opt_i,$opt_P, $opt_s,$opt_m,$opt_M,$opt_A,$opt_S,$opt_L, $opt_a, $opt_r);
my (%conv_author_name, %conv_author_email);
sub usage(;$) {
@@ -40,7 +40,7 @@ Usage: ${\basename $0} # fetch/update GIT from CVS
[-o branch-for-HEAD] [-h] [-v] [-d CVSROOT] [-A author-conv-file]
[-p opts-for-cvsps] [-P file] [-C GIT_repository] [-z fuzz] [-i] [-k]
[-u] [-s subst] [-a] [-m] [-M regex] [-S regex] [-L commitlimit]
- [CVS_module]
+ [-r remote] [CVS_module]
END
exit(1);
}
@@ -114,7 +114,7 @@ sub read_repo_config {
}
}
-my $opts = "haivmkuo:d:p:C:z:s:M:P:A:S:L:";
+my $opts = "haivmkuo:d:p:r:C:z:s:M:P:A:S:L:";
read_repo_config($opts);
getopts($opts) or usage();
usage if $opt_h;
@@ -134,13 +134,21 @@ if ($opt_d) {
} else {
usage("CVSROOT needs to be set");
}
-$opt_o ||= "origin";
$opt_s ||= "-";
$opt_a ||= 0;
my $git_tree = $opt_C;
$git_tree ||= ".";
+my $remote;
+if (defined $opt_r) {
+ $remote = 'refs/remotes/' . $opt_r;
+ $opt_o ||= "master";
+} else {
+ $opt_o ||= "origin";
+ $remote = 'refs/heads';
+}
+
my $cvs_tree;
if ($#ARGV == 0) {
$cvs_tree = $ARGV[0];
@@ -522,7 +530,7 @@ sub get_headref ($$) {
my $name = shift;
my $git_dir = shift;
- my $f = "$git_dir/refs/heads/$name";
+ my $f = "$git_dir/$remote/$name";
if (open(my $fh, $f)) {
chomp(my $r = <$fh>);
is_sha1($r) or die "Cannot get head id for $name ($r): $!";
@@ -573,12 +581,12 @@ unless (-d $git_dir) {
# Get the last import timestamps
my $fmt = '($ref, $author) = (%(refname), %(author));';
- open(H, "git-for-each-ref --perl --format='$fmt' refs/heads |") or
+ open(H, "git-for-each-ref --perl --format='$fmt' $remote |") or
die "Cannot run git-for-each-ref: $!\n";
while (defined(my $entry = <H>)) {
my ($ref, $author);
eval($entry) || die "cannot eval refs list: $@";
- my ($head) = ($ref =~ m|^refs/heads/(.*)|);
+ my ($head) = ($ref =~ m|^$remote/(.*)|);
$author =~ /^.*\s(\d+)\s[-+]\d{4}$/;
$branch_date{$head} = $1;
}
@@ -701,9 +709,9 @@ sub commit {
$index{$branch} = tmpnam();
$ENV{GIT_INDEX_FILE} = $index{$branch};
if ($ancestor) {
- system("git-read-tree", $ancestor);
+ system("git-read-tree", "$remote/$ancestor");
} else {
- system("git-read-tree", $branch);
+ system("git-read-tree", "$remote/$branch");
}
die "read-tree failed: $?\n" if $?;
}
@@ -762,7 +770,7 @@ sub commit {
waitpid($pid,0);
die "Error running git-commit-tree: $?\n" if $?;
- system("git-update-ref refs/heads/$branch $cid") == 0
+ system("git-update-ref $remote/$branch $cid") == 0
or die "Cannot write branch $branch for update: $!\n";
if ($tag) {
@@ -772,30 +780,8 @@ sub commit {
$xtag =~ tr/_/\./ if ( $opt_u );
$xtag =~ s/[\/]/$opt_s/g;
- my $pid = open2($in, $out, 'git-mktag');
- print $out "object $cid\n".
- "type commit\n".
- "tag $xtag\n".
- "tagger $author_name <$author_email>\n"
- or die "Cannot create tag object $xtag: $!\n";
- close($out)
- or die "Cannot create tag object $xtag: $!\n";
-
- my $tagobj = <$in>;
- chomp $tagobj;
-
- if ( !close($in) or waitpid($pid, 0) != $pid or
- $? != 0 or $tagobj !~ /^[0123456789abcdef]{40}$/ ) {
- die "Cannot create tag object $xtag: $!\n";
- }
-
-
- open(C,">$git_dir/refs/tags/$xtag")
+ system('git-tag', $xtag, $cid) == 0
or die "Cannot create tag $xtag: $!\n";
- print C "$tagobj\n"
- or die "Cannot write tag $xtag: $!\n";
- close(C)
- or die "Cannot write tag $xtag: $!\n";
print "Created tag '$xtag' on '$branch'\n" if $opt_v;
}
@@ -883,12 +869,12 @@ while (<CVS>) {
print STDERR "Branch $branch erroneously stems from itself -- changed ancestor to $opt_o\n";
$ancestor = $opt_o;
}
- if (-f "$git_dir/refs/heads/$branch") {
+ if (-f "$git_dir/$remote/$branch") {
print STDERR "Branch $branch already exists!\n";
$state=11;
next;
}
- unless (open(H,"$git_dir/refs/heads/$ancestor")) {
+ unless (open(H,"$git_dir/$remote/$ancestor")) {
print STDERR "Branch $ancestor does not exist!\n";
$ignorebranch{$branch} = 1;
$state=11;
@@ -896,7 +882,7 @@ while (<CVS>) {
}
chomp(my $id = <H>);
close(H);
- unless (open(H,"> $git_dir/refs/heads/$branch")) {
+ unless (open(H,"> $git_dir/$remote/$branch")) {
print STDERR "Could not create branch $branch: $!\n";
$ignorebranch{$branch} = 1;
$state=11;
@@ -1010,14 +996,16 @@ if ($orig_branch) {
die "Fast-forward update failed: $?\n" if $?;
}
else {
- system(qw(git-merge cvsimport HEAD), "refs/heads/$opt_o");
+ system(qw(git-merge cvsimport HEAD), "$remote/$opt_o");
die "Could not merge $opt_o into the current branch.\n" if $?;
}
} else {
$orig_branch = "master";
print "DONE; creating $orig_branch branch\n" if $opt_v;
- system("git-update-ref", "refs/heads/master", "refs/heads/$opt_o")
+ system("git-update-ref", "refs/heads/master", "$remote/$opt_o")
unless -f "$git_dir/refs/heads/master";
+ system("git-symbolic-ref", "$remote/HEAD", "$remote/$opt_o")
+ if ($opt_r && $opt_o ne 'HEAD');
system('git-update-ref', 'HEAD', "$orig_branch");
unless ($opt_i) {
system('git checkout');
diff --git a/git-remote.perl b/git-remote.perl
index 576379912..b59cafdf8 100755
--- a/git-remote.perl
+++ b/git-remote.perl
@@ -258,6 +258,7 @@ sub show_remote {
if ($info->{'PUSH'}) {
my @pushed = map {
s|^refs/heads/||;
+ s|^\+refs/heads/|+|;
s|:refs/heads/|:|;
$_;
} @{$info->{'PUSH'}};
diff --git a/git-svn.perl b/git-svn.perl
index e35006142..50128d728 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -38,14 +38,16 @@ use IPC::Open3;
use Git;
BEGIN {
- my $s;
+ # import functions from Git into our packages, en masse
+ no strict 'refs';
foreach (qw/command command_oneline command_noisy command_output_pipe
command_input_pipe command_close_pipe/) {
- $s .= "*SVN::Git::Editor::$_ = *SVN::Git::Fetcher::$_ = ".
- "*Git::SVN::Migration::$_ = ".
- "*Git::SVN::Log::$_ = *Git::SVN::$_ = *$_ = *Git::$_; ";
+ for my $package ( qw(SVN::Git::Editor SVN::Git::Fetcher
+ Git::SVN::Migration Git::SVN::Log Git::SVN),
+ __PACKAGE__) {
+ *{"${package}::$_"} = \&{"Git::$_"};
+ }
}
- eval $s;
}
my ($SVN);
@@ -846,26 +848,26 @@ BEGIN {
# some options are read globally, but can be overridden locally
# per [svn-remote "..."] section. Command-line options will *NOT*
# override options set in an [svn-remote "..."] section
- my $e;
- foreach (qw/follow_parent no_metadata use_svm_props
- use_svnsync_props/) {
- my $key = $_;
+ no strict 'refs';
+ for my $option (qw/follow_parent no_metadata use_svm_props
+ use_svnsync_props/) {
+ my $key = $option;
$key =~ tr/_//d;
- $e .= "sub $_ {
- my (\$self) = \@_;
- return \$self->{-$_} if exists \$self->{-$_};
- my \$k = \"svn-remote.\$self->{repo_id}\.$key\";
- eval { command_oneline(qw/config --get/, \$k) };
- if (\$@) {
- \$self->{-$_} = \$Git::SVN::_$_;
+ my $prop = "-$option";
+ *$option = sub {
+ my ($self) = @_;
+ return $self->{$prop} if exists $self->{$prop};
+ my $k = "svn-remote.$self->{repo_id}.$key";
+ eval { command_oneline(qw/config --get/, $k) };
+ if ($@) {
+ $self->{$prop} = ${"Git::SVN::_$option"};
} else {
- my \$v = command_oneline(qw/config --bool/,\$k);
- \$self->{-$_} = \$v eq 'false' ? 0 : 1;
+ my $v = command_oneline(qw/config --bool/,$k);
+ $self->{$prop} = $v eq 'false' ? 0 : 1;
}
- return \$self->{-$_} }\n";
+ return $self->{$prop};
+ }
}
- $e .= "1;\n";
- eval $e or die $@;
}
my %LOCKFILES;
@@ -1457,7 +1459,7 @@ sub tmp_config {
my (@args) = @_;
my $old_def_config = "$ENV{GIT_DIR}/svn/config";
my $config = "$ENV{GIT_DIR}/svn/.metadata";
- if (-e $old_def_config && ! -e $config) {
+ if (! -f $config && -f $old_def_config) {
rename $old_def_config, $config or
die "Failed rename $old_def_config => $config: $!\n";
}
@@ -2899,17 +2901,17 @@ my ($can_do_switch, %ignored_err, $RA);
BEGIN {
# enforce temporary pool usage for some simple functions
- my $e;
- foreach (qw/rev_proplist get_latest_revnum get_uuid get_repos_root/) {
- $e .= "sub $_ {
- my \$self = shift;
- my \$pool = SVN::Pool->new;
- my \@ret = \$self->SUPER::$_(\@_,\$pool);
- \$pool->clear;
- wantarray ? \@ret : \$ret[0]; }\n";
+ no strict 'refs';
+ for my $f (qw/rev_proplist get_latest_revnum get_uuid get_repos_root/) {
+ my $SUPER = "SUPER::$f";
+ *$f = sub {
+ my $self = shift;
+ my $pool = SVN::Pool->new;
+ my @ret = $self->$SUPER(@_,$pool);
+ $pool->clear;
+ wantarray ? @ret : $ret[0];
+ };
}
-
- eval "$e; 1;" or die $@;
}
sub new {
@@ -3072,11 +3074,8 @@ sub gs_do_switch {
$editor->{git_commit_ok};
}
-sub gs_fetch_loop_common {
- my ($self, $base, $head, $gsv, $globs) = @_;
- return if ($base > $head);
- my $inc = $_log_window_size;
- my ($min, $max) = ($base, $head < $base + $inc ? $head : $base + $inc);
+sub longest_common_path {
+ my ($gsv, $globs) = @_;
my %common;
my $common_max = scalar @$gsv;
@@ -3108,6 +3107,15 @@ sub gs_fetch_loop_common {
last;
}
}
+ $longest_path;
+}
+
+sub gs_fetch_loop_common {
+ my ($self, $base, $head, $gsv, $globs) = @_;
+ return if ($base > $head);
+ my $inc = $_log_window_size;
+ my ($min, $max) = ($base, $head < $base + $inc ? $head : $base + $inc);
+ my $longest_path = longest_common_path($gsv, $globs);
while (1) {
my %revs;
my $err;
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index a6383dc85..dbfb0441a 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -4206,8 +4206,10 @@ sub git_snapshot {
my $git = git_cmd_str();
my $name = $project;
+ $name =~ s,([^/])/*\.git$,$1,;
+ $name = basename($name);
+ my $filename = to_utf8($name);
$name =~ s/\047/\047\\\047\047/g;
- my $filename = to_utf8(basename($project));
my $cmd;
if ($suffix eq 'zip') {
$filename .= "-$hash.$suffix";
diff --git a/merge-recursive.c b/merge-recursive.c
index 4a82b741a..c8539ec0b 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -127,7 +127,7 @@ static void output(int v, const char *fmt, ...)
va_end(args);
}
-static void flush_output()
+static void flush_output(void)
{
struct output_buffer *b, *n;
for (b = output_list; b; b = n) {
diff --git a/refs.c b/refs.c
index ef4484d29..67ac97c71 100644
--- a/refs.c
+++ b/refs.c
@@ -150,7 +150,7 @@ static struct ref_list *sort_ref_list(struct ref_list *list)
* Future: need to be in "struct repository"
* when doing a full libification.
*/
-struct cached_refs {
+static struct cached_refs {
char did_loose;
char did_packed;
struct ref_list *loose;
diff --git a/remote.c b/remote.c
index 33c8e5055..54c9401a6 100644
--- a/remote.c
+++ b/remote.c
@@ -536,13 +536,14 @@ int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
}
if (pat) {
- dst_name = xmalloc(strlen(pat->dst) +
+ const char *dst_side = pat->dst ? pat->dst : pat->src;
+ dst_name = xmalloc(strlen(dst_side) +
strlen(src->name) -
strlen(pat->src) + 2);
- strcpy(dst_name, pat->dst);
+ strcpy(dst_name, dst_side);
strcat(dst_name, src->name + strlen(pat->src));
} else
- dst_name = strdup(src->name);
+ dst_name = xstrdup(src->name);
dst_peer = find_ref_by_name(dst, dst_name);
if (dst_peer && dst_peer->peer_ref)
/* We're already sending something to this ref. */
diff --git a/revision.c b/revision.c
index b12c25e2b..1f4590b89 100644
--- a/revision.c
+++ b/revision.c
@@ -1180,7 +1180,8 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
opts = diff_opt_parse(&revs->diffopt, argv+i, argc-i);
if (opts > 0) {
- revs->diff = 1;
+ if (strcmp(argv[i], "-z"))
+ revs->diff = 1;
i += opts - 1;
continue;
}
diff --git a/sha1_file.c b/sha1_file.c
index 2b860868f..7628ee97d 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -413,7 +413,7 @@ static size_t peak_pack_mapped;
static size_t pack_mapped;
struct packed_git *packed_git;
-void pack_report()
+void pack_report(void)
{
fprintf(stderr,
"pack_report: getpagesize() = %10" SZ_FMT "\n"
@@ -959,7 +959,7 @@ int check_sha1_signature(const unsigned char *sha1, void *map, unsigned long siz
return hashcmp(sha1, real_sha1) ? -1 : 0;
}
-void *map_sha1_file(const unsigned char *sha1, unsigned long *size)
+static void *map_sha1_file(const unsigned char *sha1, unsigned long *size)
{
struct stat st;
void *map;
diff --git a/t/t9113-git-svn-dcommit-new-file.sh b/t/t9113-git-svn-dcommit-new-file.sh
new file mode 100755
index 000000000..9ef0db904
--- /dev/null
+++ b/t/t9113-git-svn-dcommit-new-file.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Eric Wong
+#
+
+# Don't run this test by default unless the user really wants it
+# I don't like the idea of taking a port and possibly leaving a
+# daemon running on a users system if the test fails.
+# Not all git users will need to interact with SVN.
+test -z "$SVNSERVE_PORT" && exit 0
+
+test_description='git-svn dcommit new files over svn:// test'
+
+. ./lib-git-svn.sh
+
+start_svnserve () {
+ svnserve --listen-port $SVNSERVE_PORT \
+ --root $rawsvnrepo \
+ --listen-once \
+ --listen-host 127.0.0.1 &
+}
+
+test_expect_success 'start tracking an empty repo' "
+ svn mkdir -m 'empty dir' $svnrepo/empty-dir &&
+ echo anon-access = write >> $rawsvnrepo/conf/svnserve.conf &&
+ start_svnserve &&
+ git svn init svn://127.0.0.1:$SVNSERVE_PORT &&
+ git svn fetch
+ "
+
+test_expect_success 'create files in new directory with dcommit' "
+ mkdir git-new-dir &&
+ echo hello > git-new-dir/world &&
+ git update-index --add git-new-dir/world &&
+ git commit -m hello &&
+ start_svnserve &&
+ git svn dcommit
+ "
+
+test_done