Merge branch 'master'

This commit is contained in:
Junio C Hamano 2005-11-18 16:58:51 -08:00
commit 52b6536c62
11 changed files with 155 additions and 94 deletions

View File

@ -8,7 +8,9 @@
-t, \--tags:: -t, \--tags::
By default, the git core utilities will not fetch and store By default, the git core utilities will not fetch and store
tags under the same name as the remote repository; ask it tags under the same name as the remote repository; ask it
to do so using `--tags`. to do so using `--tags`. Using this option will bound the
list of objects pulled to the remote tags. Commits in branches
beyond the tags will be ignored.
-u, \--update-head-ok:: -u, \--update-head-ok::
By default `git-fetch` refuses to update the head which By default `git-fetch` refuses to update the head which

View File

@ -16,6 +16,14 @@ This program computes which packs in your repository
are redundant. The output is suitable for piping to are redundant. The output is suitable for piping to
'xargs rm' if you are in the root of the repository. 'xargs rm' if you are in the root of the repository.
git-pack-redundant accepts a list of objects on standard input. Any objects
given will be ignored when checking which packs are required. This makes the
following command useful when wanting to remove packs which contain unreachable
objects.
git-fsck-objects --full --unreachable | cut -d ' ' -f3 | \
git-pack-redundant --all | xargs rm
OPTIONS OPTIONS
------- -------

View File

@ -208,6 +208,10 @@ endif
ifeq ($(uname_O),Cygwin) ifeq ($(uname_O),Cygwin)
NO_STRCASESTR = YesPlease NO_STRCASESTR = YesPlease
NEEDS_LIBICONV = YesPlease NEEDS_LIBICONV = YesPlease
# There are conflicting reports about this.
# On some boxes NO_MMAP is needed, and not so elsewhere.
# Try uncommenting this if you see things break -- YMMV.
# NO_MMAP = YesPlease
NO_IPV6 = YesPlease NO_IPV6 = YesPlease
X = .exe X = .exe
ALL_CFLAGS += -DUSE_SYMLINK_HEAD=0 ALL_CFLAGS += -DUSE_SYMLINK_HEAD=0

54
date.c
View File

@ -468,12 +468,52 @@ static void update_tm(struct tm *tm, unsigned long sec)
localtime_r(&n, tm); localtime_r(&n, tm);
} }
static void date_yesterday(struct tm *tm, int *num)
{
update_tm(tm, 24*60*60);
}
static void date_time(struct tm *tm, int hour)
{
if (tm->tm_hour < hour)
date_yesterday(tm, NULL);
tm->tm_hour = hour;
tm->tm_min = 0;
tm->tm_sec = 0;
}
static void date_midnight(struct tm *tm, int *num)
{
date_time(tm, 0);
}
static void date_noon(struct tm *tm, int *num)
{
date_time(tm, 12);
}
static void date_tea(struct tm *tm, int *num)
{
date_time(tm, 17);
}
static const struct special {
const char *name;
void (*fn)(struct tm *, int *);
} special[] = {
{ "yesterday", date_yesterday },
{ "noon", date_noon },
{ "midnight", date_midnight },
{ "tea", date_tea },
{ NULL }
};
static const char *number_name[] = { static const char *number_name[] = {
"zero", "one", "two", "three", "four", "zero", "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine", "ten", "five", "six", "seven", "eight", "nine", "ten",
}; };
static struct typelen { static const struct typelen {
const char *type; const char *type;
int length; int length;
} typelen[] = { } typelen[] = {
@ -487,7 +527,8 @@ static struct typelen {
static const char *approxidate_alpha(const char *date, struct tm *tm, int *num) static const char *approxidate_alpha(const char *date, struct tm *tm, int *num)
{ {
struct typelen *tl; const struct typelen *tl;
const struct special *s;
const char *end = date; const char *end = date;
int n = 1, i; int n = 1, i;
@ -502,9 +543,12 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, int *num)
} }
} }
if (match_string(date, "yesterday") > 8) { for (s = special; s->name; s++) {
update_tm(tm, 24*60*60); int len = strlen(s->name);
return end; if (match_string(date, s->name) == len) {
s->fn(tm, num);
return end;
}
} }
if (!*num) { if (!*num) {

View File

@ -3,7 +3,7 @@
. git-sh-setup || die "Not a git archive" . git-sh-setup || die "Not a git archive"
usage () { usage () {
echo >&2 "usage: $(basename $0)"' [-d <branch>] | [<branch> [start-point]] echo >&2 "usage: $(basename $0)"' [-d <branch>] | [[-f] <branch> [start-point]]
If no arguments, show available branches and mark current branch with a star. If no arguments, show available branches and mark current branch with a star.
If one argument, create a new branch <branchname> based off of current HEAD. If one argument, create a new branch <branchname> based off of current HEAD.
@ -12,11 +12,12 @@ If two arguments, create a new branch <branchname> based off of <start-point>.
exit 1 exit 1
} }
headref=$(GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD |
sed -e 's|^refs/heads/||')
delete_branch () { delete_branch () {
option="$1" option="$1"
shift shift
headref=$(GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD |
sed -e 's|^refs/heads/||')
for branch_name for branch_name
do do
case ",$headref," in case ",$headref," in
@ -52,6 +53,7 @@ delete_branch () {
exit 0 exit 0
} }
force=
while case "$#,$1" in 0,*) break ;; *,-*) ;; *) break ;; esac while case "$#,$1" in 0,*) break ;; *,-*) ;; *) break ;; esac
do do
case "$1" in case "$1" in
@ -59,6 +61,9 @@ do
delete_branch "$@" delete_branch "$@"
exit exit
;; ;;
-f)
force="$1"
;;
--) --)
shift shift
break break
@ -72,8 +77,6 @@ done
case "$#" in case "$#" in
0) 0)
headref=$(GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD |
sed -e 's|^refs/heads/||')
git-rev-parse --symbolic --all | git-rev-parse --symbolic --all |
sed -ne 's|^refs/heads/||p' | sed -ne 's|^refs/heads/||p' |
sort | sort |
@ -97,10 +100,18 @@ branchname="$1"
rev=$(git-rev-parse --verify "$head") || exit rev=$(git-rev-parse --verify "$head") || exit
[ -e "$GIT_DIR/refs/heads/$branchname" ] &&
die "$branchname already exists."
git-check-ref-format "heads/$branchname" || git-check-ref-format "heads/$branchname" ||
die "we do not like '$branchname' as a branch name." die "we do not like '$branchname' as a branch name."
if [ -e "$GIT_DIR/refs/heads/$branchname" ]
then
if test '' = "$force"
then
die "$branchname already exists."
elif test "$branchname" = "$headref"
then
die "cannot force-update the current branch."
fi
fi
git update-ref "refs/heads/$branchname" $rev git update-ref "refs/heads/$branchname" $rev

View File

@ -12,6 +12,7 @@ IFS="$LF"
tags= tags=
append= append=
force= force=
verbose=
update_head_ok= update_head_ok=
while case "$#" in 0) break ;; esac while case "$#" in 0) break ;; esac
do do
@ -30,6 +31,9 @@ do
--update-head-o|--update-head-ok) --update-head-o|--update-head-ok)
update_head_ok=t update_head_ok=t
;; ;;
-v|--verbose)
verbose=Yes
;;
*) *)
break break
;; ;;
@ -91,12 +95,12 @@ append_fetch_head () {
then then
headc_=$(git-rev-parse --verify "$head_^0") || exit headc_=$(git-rev-parse --verify "$head_^0") || exit
echo "$headc_ $not_for_merge_ $note_" >>"$GIT_DIR/FETCH_HEAD" echo "$headc_ $not_for_merge_ $note_" >>"$GIT_DIR/FETCH_HEAD"
echo >&2 "* committish: $head_" [ "$verbose" ] && echo >&2 "* committish: $head_"
echo >&2 " $note_" [ "$verbose" ] && echo >&2 " $note_"
else else
echo "$head_ not-for-merge $note_" >>"$GIT_DIR/FETCH_HEAD" echo "$head_ not-for-merge $note_" >>"$GIT_DIR/FETCH_HEAD"
echo >&2 "* non-commit: $head_" [ "$verbose" ] && echo >&2 "* non-commit: $head_"
echo >&2 " $note_" [ "$verbose" ] && echo >&2 " $note_"
fi fi
if test "$local_name_" != "" if test "$local_name_" != ""
then then
@ -116,7 +120,7 @@ fast_forward_local () {
then then
if now_=$(cat "$GIT_DIR/$1") && test "$now_" = "$2" if now_=$(cat "$GIT_DIR/$1") && test "$now_" = "$2"
then then
echo >&2 "* $1: same as $3" [ "$verbose" ] && echo >&2 "* $1: same as $3"
else else
echo >&2 "* $1: updating with $3" echo >&2 "* $1: updating with $3"
fi fi

View File

@ -31,7 +31,7 @@ git-prune-packed $dryrun
redundant=$(git-pack-redundant --all) redundant=$(git-pack-redundant --all)
if test "" != "$redundant" if test "" != "$redundant"
then then
if test "" = $dryrun if test "" = "$dryrun"
then then
echo "$redundant" | xargs rm -f echo "$redundant" | xargs rm -f
else else

View File

@ -5,65 +5,25 @@
. git-sh-setup || die "Not a git archive." . git-sh-setup || die "Not a git archive."
usage="usage: $0 "'<upstream> [<head>] # The other head is given
other=$(git-rev-parse --verify "$1^0") || exit
Uses output from git-cherry to rebase local commits to the new head of
upstream tree.'
case "$#,$1" in
1,*..*)
upstream=$(expr "$1" : '\(.*\)\.\.') ours=$(expr "$1" : '.*\.\.\(.*\)$')
set x "$upstream" "$ours"
shift ;;
esac
# The tree must be really really clean.
git-update-index --refresh || exit git-update-index --refresh || exit
diff=$(git-diff-index --cached --name-status -r HEAD)
case "$#" in case "$different" in
1) ours_symbolic=HEAD ;; ?*) echo "$diff"
2) ours_symbolic="$2" ;; exit 1
*) die "$usage" ;; ;;
esac esac
upstream=`git-rev-parse --verify "$1"` && # If the branch to rebase is given, first switch to it.
ours=`git-rev-parse --verify "$ours_symbolic"` || exit case "$#" in
different1=$(git-diff-index --name-only --cached "$ours") && 2)
different2=$(git-diff-index --name-only "$ours") && git-checkout "$2" || exit
test "$different1$different2" = "" || esac
die "Your working tree does not match $ours_symbolic."
git-read-tree -m -u $ours $upstream && # Rewind the head to "$other"
new_head=$(git-rev-parse --verify "$upstream^0") && git-reset --hard "$other"
git-update-ref HEAD "$new_head" || exit git-format-patch -k --stdout --full-index "$other" ORIG_HEAD |
git am --binary -3 -k
tmp=.rebase-tmp$$
fail=$tmp-fail
trap "rm -rf $tmp-*" 1 2 3 15
>$fail
git-cherry -v $upstream $ours |
while read sign commit msg
do
case "$sign" in
-)
echo >&2 "* Already applied: $msg"
continue ;;
esac
echo >&2 "* Applying: $msg"
S=$(git-rev-parse --verify HEAD) &&
git-cherry-pick --replay $commit || {
echo >&2 "* Not applying the patch and continuing."
echo $commit >>$fail
git-reset --hard $S
}
done
if test -s $fail
then
echo >&2 Some commits could not be rebased, check by hand:
cat >&2 $fail
echo >&2 "(the same list of commits are found in $tmp)"
exit 1
else
rm -f $fail
fi

View File

@ -63,9 +63,22 @@ exit
if test "$remove_redundant" = t if test "$remove_redundant" = t
then then
sync sync
redundant=$(git-pack-redundant --all) if test "$all_into_one" = t
if test "$redundant" != "" ; then then
echo $redundant | xargs rm cd "$PACKDIR"
existing=`find . -type f \( -name '*.pack' -o -name '*.idx' \) -print`
for e in $existing
do
case "$e" in
./pack-$name.pack | ./pack-$name.idx) ;;
*) rm -f $e ;;
esac
done
else
redundant=$(git-pack-redundant --all)
if test "$redundant" != "" ; then
echo $redundant | xargs rm
fi
fi fi
fi fi

5
git.c
View File

@ -59,7 +59,8 @@ static void add_cmdname(const char *name, int len)
if (!ent) if (!ent)
oom(); oom();
ent->len = len; ent->len = len;
memcpy(ent->name, name, len+1); memcpy(ent->name, name, len);
ent->name[len] = 0;
cmdname[cmdname_cnt++] = ent; cmdname[cmdname_cnt++] = ent;
} }
@ -132,6 +133,8 @@ static void list_commands(const char *exec_path, const char *pattern)
continue; continue;
entlen = strlen(de->d_name); entlen = strlen(de->d_name);
if (4 < entlen && !strcmp(de->d_name + entlen - 4, ".exe"))
entlen -= 4;
if (longest < entlen) if (longest < entlen)
longest = entlen; longest = entlen;

View File

@ -291,6 +291,7 @@ struct pll * get_all_permutations(struct pack_list *list)
hint[0] = new_pll; hint[0] = new_pll;
new_pll->next = NULL; new_pll->next = NULL;
new_pll->pl = list; new_pll->pl = list;
new_pll->pl_size = 1;
return new_pll; return new_pll;
} }
@ -439,7 +440,7 @@ void minimize(struct pack_list **min)
break; /* ignore all larger permutations */ break; /* ignore all larger permutations */
if (is_superset(perm->pl, missing)) { if (is_superset(perm->pl, missing)) {
new_perm = xmalloc(sizeof(struct pll)); new_perm = xmalloc(sizeof(struct pll));
new_perm->pl = perm->pl; memcpy(new_perm, perm, sizeof(struct pll));
new_perm->next = perm_ok; new_perm->next = perm_ok;
perm_ok = new_perm; perm_ok = new_perm;
} }
@ -496,7 +497,7 @@ void load_all_objects()
} }
/* this scales like O(n^2) */ /* this scales like O(n^2) */
void cmp_packs() void cmp_local_packs()
{ {
struct pack_list *subset, *pl = local_packs; struct pack_list *subset, *pl = local_packs;
@ -505,16 +506,21 @@ void cmp_packs()
cmp_two_packs(pl, subset); cmp_two_packs(pl, subset);
pl = pl->next; pl = pl->next;
} }
}
pl = altodb_packs; void scan_alt_odb_packs()
while (pl) { {
subset = local_packs; struct pack_list *local, *alt;
while (subset) {
llist_sorted_difference_inplace(subset->unique_objects, alt = altodb_packs;
pl->all_objects); while (alt) {
subset = subset->next; local = local_packs;
while (local) {
llist_sorted_difference_inplace(local->unique_objects,
alt->all_objects);
local = local->next;
} }
pl = pl->next; alt = alt->next;
} }
} }
@ -524,6 +530,9 @@ struct pack_list * add_pack(struct packed_git *p)
size_t off; size_t off;
void *base; void *base;
if (!p->pack_local && !(alt_odb || verbose))
return NULL;
l.pack = p; l.pack = p;
llist_init(&l.all_objects); llist_init(&l.all_objects);
@ -531,14 +540,14 @@ struct pack_list * add_pack(struct packed_git *p)
base = (void *)p->index_base; base = (void *)p->index_base;
while (off <= p->index_size - 3 * 20) { while (off <= p->index_size - 3 * 20) {
llist_insert_back(l.all_objects, base + off); llist_insert_back(l.all_objects, base + off);
off+=24; off += 24;
} }
/* this list will be pruned in cmp_two_packs later */ /* this list will be pruned in cmp_two_packs later */
l.unique_objects = llist_copy(l.all_objects); l.unique_objects = llist_copy(l.all_objects);
if (p->pack_local) if (p->pack_local)
return pack_list_insert(&local_packs, &l); return pack_list_insert(&local_packs, &l);
else else
return alt_odb ? pack_list_insert(&altodb_packs, &l) : NULL; return pack_list_insert(&altodb_packs, &l);
} }
struct pack_list * add_pack_file(char *filename) struct pack_list * add_pack_file(char *filename)
@ -606,11 +615,14 @@ int main(int argc, char **argv)
if (local_packs == NULL) if (local_packs == NULL)
die("Zero packs found!\n"); die("Zero packs found!\n");
cmp_packs();
load_all_objects(); load_all_objects();
cmp_local_packs();
if (alt_odb)
scan_alt_odb_packs();
minimize(&min); minimize(&min);
if (verbose) { if (verbose) {
fprintf(stderr, "There are %lu packs available in alt-odbs.\n", fprintf(stderr, "There are %lu packs available in alt-odbs.\n",
(unsigned long)pack_list_size(altodb_packs)); (unsigned long)pack_list_size(altodb_packs));