* 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:
Junio C Hamano 2010-10-06 12:10:02 -07:00
Родитель 931c103320 6db2103f92
Коммит 90215bf300
16 изменённых файлов: 135 добавлений и 42 удалений

Просмотреть файл

@ -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
Просмотреть файл

@ -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(&regex);
}
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

Просмотреть файл

@ -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');