Merge branch 'maint'
* maint: Documentation/git-clone: describe --mirror more verbosely do not depend on signed integer overflow work around buggy S_ISxxx(m) implementations xdiff: cast arguments for ctype functions to unsigned char init: plug tiny one-time memory leak diffcore-pickaxe.c: remove unnecessary curly braces t3020 (ls-files-error-unmatch): remove stray '1' from end of file setup: make sure git dir path is in a permanent buffer environment.c: remove unused variable git-svn: fix processing of decorated commit hashes git-svn: check_cherry_pick should exclude commits already in our history Documentation/git-svn: discourage "noMetadata"
This commit is contained in:
commit
90215bf300
@ -128,7 +128,12 @@ objects from the source repository into a pack in the cloned repository.
|
||||
configuration variables are created.
|
||||
|
||||
--mirror::
|
||||
Set up a mirror of the remote repository. This implies `--bare`.
|
||||
Set up a mirror of the source repository. This implies `--bare`.
|
||||
Compared to `--bare`, `--mirror` not only maps local branches of the
|
||||
source to local branches of the target, it maps all refs (including
|
||||
remote branches, notes etc.) and sets up a refspec configuration such
|
||||
that all these refs are overwritten by a `git remote update` in the
|
||||
target repository.
|
||||
|
||||
--origin <name>::
|
||||
-o <name>::
|
||||
|
@ -56,6 +56,8 @@ COMMANDS
|
||||
as well, they take precedence.
|
||||
--no-metadata;;
|
||||
Set the 'noMetadata' option in the [svn-remote] config.
|
||||
This option is not recommended, please read the 'svn.noMetadata'
|
||||
section of this manpage before using this option.
|
||||
--use-svm-props;;
|
||||
Set the 'useSvmProps' option in the [svn-remote] config.
|
||||
--use-svnsync-props;;
|
||||
@ -597,13 +599,22 @@ svn.noMetadata::
|
||||
svn-remote.<name>.noMetadata::
|
||||
This gets rid of the 'git-svn-id:' lines at the end of every commit.
|
||||
+
|
||||
If you lose your .git/svn/git-svn/.rev_db file, 'git svn' will not
|
||||
be able to rebuild it and you won't be able to fetch again,
|
||||
either. This is fine for one-shot imports.
|
||||
This option can only be used for one-shot imports as 'git svn'
|
||||
will not be able to fetch again without metadata. Additionally,
|
||||
if you lose your .git/svn/**/.rev_map.* files, 'git svn' will not
|
||||
be able to rebuild them.
|
||||
+
|
||||
The 'git svn log' command will not work on repositories using
|
||||
this, either. Using this conflicts with the 'useSvmProps'
|
||||
option for (hopefully) obvious reasons.
|
||||
+
|
||||
This option is NOT recommended as it makes it difficult to track down
|
||||
old references to SVN revision numbers in existing documentation, bug
|
||||
reports and archives. If you plan to eventually migrate from SVN to git
|
||||
and are certain about dropping SVN history, consider
|
||||
linkgit:git-filter-branch[1] instead. filter-branch also allows
|
||||
reformating of metadata for ease-of-reading and rewriting authorship
|
||||
info for non-"svn.authorsFile" users.
|
||||
|
||||
svn.useSvmProps::
|
||||
svn-remote.<name>.useSvmProps::
|
||||
|
@ -161,7 +161,7 @@ static void use(int bytes)
|
||||
input_offset += bytes;
|
||||
|
||||
/* make sure off_t is sufficiently large not to wrap */
|
||||
if (consumed_bytes > consumed_bytes + bytes)
|
||||
if (signed_add_overflows(consumed_bytes, bytes))
|
||||
die("pack too large for current definition of off_t");
|
||||
consumed_bytes += bytes;
|
||||
}
|
||||
|
@ -294,11 +294,26 @@ static int create_default_files(const char *template_path)
|
||||
return reinit;
|
||||
}
|
||||
|
||||
static void create_object_directory(void)
|
||||
{
|
||||
const char *object_directory = get_object_directory();
|
||||
int len = strlen(object_directory);
|
||||
char *path = xmalloc(len + 40);
|
||||
|
||||
memcpy(path, object_directory, len);
|
||||
|
||||
safe_create_dir(object_directory, 1);
|
||||
strcpy(path+len, "/pack");
|
||||
safe_create_dir(path, 1);
|
||||
strcpy(path+len, "/info");
|
||||
safe_create_dir(path, 1);
|
||||
|
||||
free(path);
|
||||
}
|
||||
|
||||
int init_db(const char *template_dir, unsigned int flags)
|
||||
{
|
||||
const char *sha1_dir;
|
||||
char *path;
|
||||
int len, reinit;
|
||||
int reinit;
|
||||
|
||||
safe_create_dir(get_git_dir(), 0);
|
||||
|
||||
@ -313,16 +328,7 @@ int init_db(const char *template_dir, unsigned int flags)
|
||||
|
||||
reinit = create_default_files(template_dir);
|
||||
|
||||
sha1_dir = get_object_directory();
|
||||
len = strlen(sha1_dir);
|
||||
path = xmalloc(len + 40);
|
||||
memcpy(path, sha1_dir, len);
|
||||
|
||||
safe_create_dir(sha1_dir, 1);
|
||||
strcpy(path+len, "/pack");
|
||||
safe_create_dir(path, 1);
|
||||
strcpy(path+len, "/info");
|
||||
safe_create_dir(path, 1);
|
||||
create_object_directory();
|
||||
|
||||
if (shared_repository) {
|
||||
char buf[10];
|
||||
|
@ -431,7 +431,7 @@ static int write_one(struct sha1file *f,
|
||||
written_list[nr_written++] = &e->idx;
|
||||
|
||||
/* make sure off_t is sufficiently large not to wrap */
|
||||
if (*offset > *offset + size)
|
||||
if (signed_add_overflows(*offset, size))
|
||||
die("pack too large for current definition of off_t");
|
||||
*offset += size;
|
||||
return 1;
|
||||
|
@ -83,7 +83,7 @@ static void use(int bytes)
|
||||
offset += bytes;
|
||||
|
||||
/* make sure off_t is sufficiently large not to wrap */
|
||||
if (consumed_bytes > consumed_bytes + bytes)
|
||||
if (signed_add_overflows(consumed_bytes, bytes))
|
||||
die("pack too large for current definition of off_t");
|
||||
consumed_bytes += bytes;
|
||||
}
|
||||
|
13
cache.h
13
cache.h
@ -277,9 +277,16 @@ static inline int ce_to_dtype(const struct cache_entry *ce)
|
||||
else
|
||||
return DT_UNKNOWN;
|
||||
}
|
||||
#define canon_mode(mode) \
|
||||
(S_ISREG(mode) ? (S_IFREG | ce_permissions(mode)) : \
|
||||
S_ISLNK(mode) ? S_IFLNK : S_ISDIR(mode) ? S_IFDIR : S_IFGITLINK)
|
||||
static inline unsigned int canon_mode(unsigned int mode)
|
||||
{
|
||||
if (S_ISREG(mode))
|
||||
return S_IFREG | ce_permissions(mode);
|
||||
if (S_ISLNK(mode))
|
||||
return S_IFLNK;
|
||||
if (S_ISDIR(mode))
|
||||
return S_IFDIR;
|
||||
return S_IFGITLINK;
|
||||
}
|
||||
|
||||
#define flexible_size(STRUCT,len) ((offsetof(struct STRUCT,name) + (len) + 8) & ~7)
|
||||
#define cache_entry_size(len) flexible_size(cache_entry,len)
|
||||
|
@ -269,9 +269,8 @@ static void diffcore_pickaxe_count(struct diff_options *o)
|
||||
diff_free_filepair(p);
|
||||
}
|
||||
|
||||
if (opts & DIFF_PICKAXE_REGEX) {
|
||||
if (opts & DIFF_PICKAXE_REGEX)
|
||||
regfree(®ex);
|
||||
}
|
||||
|
||||
free(q->queue);
|
||||
*q = outq;
|
||||
|
@ -64,7 +64,7 @@ char *git_work_tree_cfg;
|
||||
static char *work_tree;
|
||||
|
||||
static const char *git_dir;
|
||||
static char *git_object_dir, *git_index_file, *git_refs_dir, *git_graft_file;
|
||||
static char *git_object_dir, *git_index_file, *git_graft_file;
|
||||
|
||||
/*
|
||||
* Repository-local GIT_* environment variables
|
||||
@ -87,8 +87,10 @@ const char * const local_repo_env[LOCAL_REPO_ENV_SIZE + 1] = {
|
||||
static void setup_git_env(void)
|
||||
{
|
||||
git_dir = getenv(GIT_DIR_ENVIRONMENT);
|
||||
if (!git_dir)
|
||||
if (!git_dir) {
|
||||
git_dir = read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT);
|
||||
git_dir = git_dir ? xstrdup(git_dir) : NULL;
|
||||
}
|
||||
if (!git_dir)
|
||||
git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
|
||||
git_object_dir = getenv(DB_ENVIRONMENT);
|
||||
@ -96,8 +98,6 @@ static void setup_git_env(void)
|
||||
git_object_dir = xmalloc(strlen(git_dir) + 9);
|
||||
sprintf(git_object_dir, "%s/objects", git_dir);
|
||||
}
|
||||
git_refs_dir = xmalloc(strlen(git_dir) + 6);
|
||||
sprintf(git_refs_dir, "%s/refs", git_dir);
|
||||
git_index_file = getenv(INDEX_ENVIRONMENT);
|
||||
if (!git_index_file) {
|
||||
git_index_file = xmalloc(strlen(git_dir) + 7);
|
||||
|
@ -28,6 +28,18 @@
|
||||
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
|
||||
#define bitsizeof(x) (CHAR_BIT * sizeof(x))
|
||||
|
||||
#define maximum_signed_value_of_type(a) \
|
||||
(INTMAX_MAX >> (bitsizeof(intmax_t) - bitsizeof(a)))
|
||||
|
||||
/*
|
||||
* Signed integer overflow is undefined in C, so here's a helper macro
|
||||
* to detect if the sum of two integers will overflow.
|
||||
*
|
||||
* Requires: a >= 0, typeof(a) equals typeof(b)
|
||||
*/
|
||||
#define signed_add_overflows(a, b) \
|
||||
((b) > maximum_signed_value_of_type(a) - (a))
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define TYPEOF(x) (__typeof__(x))
|
||||
#else
|
||||
|
@ -1513,7 +1513,8 @@ sub cmt_sha2rev_batch {
|
||||
|
||||
sub working_head_info {
|
||||
my ($head, $refs) = @_;
|
||||
my @args = ('log', '--no-color', '--first-parent', '--pretty=medium');
|
||||
my @args = qw/log --no-color --no-decorate --first-parent
|
||||
--pretty=medium/;
|
||||
my ($fh, $ctx) = command_output_pipe(@args, $head);
|
||||
my $hash;
|
||||
my %max;
|
||||
@ -3118,9 +3119,10 @@ sub _rev_list {
|
||||
sub check_cherry_pick {
|
||||
my $base = shift;
|
||||
my $tip = shift;
|
||||
my $parents = shift;
|
||||
my @ranges = @_;
|
||||
my %commits = map { $_ => 1 }
|
||||
_rev_list("--no-merges", $tip, "--not", $base);
|
||||
_rev_list("--no-merges", $tip, "--not", $base, @$parents);
|
||||
for my $range ( @ranges ) {
|
||||
delete @commits{_rev_list($range)};
|
||||
}
|
||||
@ -3296,6 +3298,7 @@ sub find_extra_svn_parents {
|
||||
# double check that there are no missing non-merge commits
|
||||
my (@incomplete) = check_cherry_pick(
|
||||
$merge_base, $merge_tip,
|
||||
$parents,
|
||||
@$ranges,
|
||||
);
|
||||
|
||||
|
@ -26,4 +26,3 @@ test_expect_success \
|
||||
'git ls-files --error-unmatch foo bar'
|
||||
|
||||
test_done
|
||||
1
|
||||
|
50
t/t9157-git-svn-fetch-merge.sh
Normal file
50
t/t9157-git-svn-fetch-merge.sh
Normal file
@ -0,0 +1,50 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2010 Steven Walter
|
||||
#
|
||||
|
||||
test_description='git svn merge detection'
|
||||
. ./lib-git-svn.sh
|
||||
|
||||
test_expect_success 'initialize source svn repo' '
|
||||
svn_cmd mkdir -m x "$svnrepo"/trunk &&
|
||||
svn_cmd mkdir -m x "$svnrepo"/branches &&
|
||||
svn_cmd co "$svnrepo"/trunk "$SVN_TREE" &&
|
||||
(
|
||||
cd "$SVN_TREE" &&
|
||||
touch foo &&
|
||||
svn add foo &&
|
||||
svn commit -m "initial commit" &&
|
||||
svn cp -m branch "$svnrepo"/trunk "$svnrepo"/branches/branch1 &&
|
||||
touch bar &&
|
||||
svn add bar &&
|
||||
svn commit -m x &&
|
||||
svn cp -m branch "$svnrepo"/trunk "$svnrepo"/branches/branch2 &&
|
||||
svn switch "$svnrepo"/branches/branch1 &&
|
||||
touch baz &&
|
||||
svn add baz &&
|
||||
svn commit -m x &&
|
||||
svn switch "$svnrepo"/trunk &&
|
||||
svn merge "$svnrepo"/branches/branch1 &&
|
||||
svn commit -m "merge" &&
|
||||
svn switch "$svnrepo"/branches/branch1 &&
|
||||
svn commit -m x &&
|
||||
svn switch "$svnrepo"/branches/branch2 &&
|
||||
svn merge "$svnrepo"/branches/branch1 &&
|
||||
svn commit -m "merge branch1" &&
|
||||
svn switch "$svnrepo"/trunk &&
|
||||
svn merge "$svnrepo"/branches/branch2 &&
|
||||
svn resolved baz &&
|
||||
svn commit -m "merge branch2"
|
||||
) &&
|
||||
rm -rf "$SVN_TREE"
|
||||
'
|
||||
|
||||
test_expect_success 'clone svn repo' '
|
||||
git svn init -s "$svnrepo" &&
|
||||
git svn fetch
|
||||
'
|
||||
|
||||
test_expect_success 'verify merge commit' 'git rev-parse HEAD^2'
|
||||
|
||||
test_done
|
@ -30,6 +30,7 @@
|
||||
#define XDL_MAX(a, b) ((a) > (b) ? (a): (b))
|
||||
#define XDL_ABS(v) ((v) >= 0 ? (v): -(v))
|
||||
#define XDL_ISDIGIT(c) ((c) >= '0' && (c) <= '9')
|
||||
#define XDL_ISSPACE(c) (isspace((unsigned char)(c)))
|
||||
#define XDL_ADDBITS(v,b) ((v) + ((v) >> (b)))
|
||||
#define XDL_MASKBITS(b) ((1UL << (b)) - 1)
|
||||
#define XDL_HASHLONG(v,b) (XDL_ADDBITS((unsigned long)(v), b) & XDL_MASKBITS(b))
|
||||
|
@ -336,7 +336,7 @@ static int xdl_refine_conflicts(xdfenv_t *xe1, xdfenv_t *xe2, xdmerge_t *m,
|
||||
static int line_contains_alnum(const char *ptr, long size)
|
||||
{
|
||||
while (size--)
|
||||
if (isalnum(*(ptr++)))
|
||||
if (isalnum((unsigned char)*(ptr++)))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -211,18 +211,18 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
|
||||
if (l1[i1++] != l2[i2++])
|
||||
return 0;
|
||||
skip_ws:
|
||||
while (i1 < s1 && isspace(l1[i1]))
|
||||
while (i1 < s1 && XDL_ISSPACE(l1[i1]))
|
||||
i1++;
|
||||
while (i2 < s2 && isspace(l2[i2]))
|
||||
while (i2 < s2 && XDL_ISSPACE(l2[i2]))
|
||||
i2++;
|
||||
}
|
||||
} else if (flags & XDF_IGNORE_WHITESPACE_CHANGE) {
|
||||
while (i1 < s1 && i2 < s2) {
|
||||
if (isspace(l1[i1]) && isspace(l2[i2])) {
|
||||
if (XDL_ISSPACE(l1[i1]) && XDL_ISSPACE(l2[i2])) {
|
||||
/* Skip matching spaces and try again */
|
||||
while (i1 < s1 && isspace(l1[i1]))
|
||||
while (i1 < s1 && XDL_ISSPACE(l1[i1]))
|
||||
i1++;
|
||||
while (i2 < s2 && isspace(l2[i2]))
|
||||
while (i2 < s2 && XDL_ISSPACE(l2[i2]))
|
||||
i2++;
|
||||
continue;
|
||||
}
|
||||
@ -241,13 +241,13 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
|
||||
* while there still are characters remaining on both lines.
|
||||
*/
|
||||
if (i1 < s1) {
|
||||
while (i1 < s1 && isspace(l1[i1]))
|
||||
while (i1 < s1 && XDL_ISSPACE(l1[i1]))
|
||||
i1++;
|
||||
if (s1 != i1)
|
||||
return 0;
|
||||
}
|
||||
if (i2 < s2) {
|
||||
while (i2 < s2 && isspace(l2[i2]))
|
||||
while (i2 < s2 && XDL_ISSPACE(l2[i2]))
|
||||
i2++;
|
||||
return (s2 == i2);
|
||||
}
|
||||
@ -260,10 +260,10 @@ static unsigned long xdl_hash_record_with_whitespace(char const **data,
|
||||
char const *ptr = *data;
|
||||
|
||||
for (; ptr < top && *ptr != '\n'; ptr++) {
|
||||
if (isspace(*ptr)) {
|
||||
if (XDL_ISSPACE(*ptr)) {
|
||||
const char *ptr2 = ptr;
|
||||
int at_eol;
|
||||
while (ptr + 1 < top && isspace(ptr[1])
|
||||
while (ptr + 1 < top && XDL_ISSPACE(ptr[1])
|
||||
&& ptr[1] != '\n')
|
||||
ptr++;
|
||||
at_eol = (top <= ptr + 1 || ptr[1] == '\n');
|
||||
|
Loading…
Reference in New Issue
Block a user