* [PATCH 2/4] Add documentation for git-pack-intersect
From: Lukas Sandström @ 2005-11-09 1:23 UTC (permalink / raw)
To: git; +Cc: Lukas Sandström, junkio
In-Reply-To: <43714EFB.5070705@etek.chalmers.se>
Add documentation for git-pack-intersect
Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
---
Documentation/git-pack-intersect.txt | 47 ++++++++++++++++++++++++++++++++++
1 files changed, 47 insertions(+), 0 deletions(-)
create mode 100644 Documentation/git-pack-intersect.txt
applies-to: 2746df1385345537edc41746b191c67ee98eea20
a1b6ab6c15c3b782478a524a7fd7791ba92960e6
diff --git a/Documentation/git-pack-intersect.txt b/Documentation/git-pack-intersect.txt
new file mode 100644
index 0000000..a73d9e3
--- /dev/null
+++ b/Documentation/git-pack-intersect.txt
@@ -0,0 +1,47 @@
+git-pack-intersect(1)
+=====================
+
+NAME
+----
+git-pack-intersect - Program used to find redundant pack files.
+
+
+SYNOPSIS
+--------
+'git-pack-intersect [ -v ] < -a | .pack filename ... >'
+
+DESCRIPTION
+-----------
+This program computes which packs in your repository
+are redundant. The output is suitable for piping to
+'xargs rm' if you are in the root of the repository.
+
+OPTIONS
+-------
+
+-v::
+ Verbose. Outputs some statistics to stderr.
+ Has a small performance penalty.
+
+-a::
+ All. Processes all the local packs. Any filenames on
+ the commandline are ignored.
+
+Author
+------
+Written by Lukas Sandström <lukass@etek.chalmers.se>
+
+Documentation
+--------------
+Documentation by Lukas Sandström <lukass@etek.chalmers.se>
+
+See-Also
+--------
+gitlink:git-pack-objects[1]
+gitlink:git-repack[1]
+gitlink:git-prune-packed[1]
+
+GIT
+---
+Part of the gitlink:git[7] suite
+
---
0.99.9.GIT
^ permalink raw reply related
* Re: Comments on recursive merge..
From: Linus Torvalds @ 2005-11-09 1:22 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vlkzyd4aq.fsf@assigned-by-dhcp.cox.net>
On Tue, 8 Nov 2005, Junio C Hamano wrote:
>
> I did show-branch soon after we worked on those pathlogical
> merge-base fix, so I would be a bit surprised if I did it
> without using all the knowledge from that exercise, but I do not
> remember offhand. The core logic should be simple
> generalization of two-head merge-base to N heads.
Hmm.
Look at the "join_revs()" logic, and tell me I'm crazy.
It does:
struct commit *commit = pop_one_commit(list_p);
int still_interesting = !!interesting(*list_p);
in that order: it looks whether there are any interesting commits left
_after_ it has popped the top-of-stack.
Which means that "still_interesting" can go down to zero if we just popped
the last interesting thing off the stack.
Which seems wrong, because the thing we just popped off the stack could
easily itself be interesting (in fact, it should be so, 99% of the time),
and can cause other interesting commits to be populated back onto the
list. So the "still_interesting" flag seems to be wrongly computed: the
way it is computed now, it's meaningless.
In contrast, the "merge_base()" thing does
while (interesting(list)) {
..
}
which means that we really will walk the list until there is nothing
interesting left. Which is admittedly expensive, but it was how we got rid
of the pathological case.
But maybe I'm just missing something really subtle. Maybe git-show-branch
does some really clever optimization that is valid.
Linus
^ permalink raw reply
* [PATCH 1/4] Add git-pack-intersect
From: Lukas Sandström @ 2005-11-09 1:22 UTC (permalink / raw)
To: git; +Cc: Lukas Sandström, junkio
In-Reply-To: <43714EFB.5070705@etek.chalmers.se>
Add git-pack-intersect
This patch adds the program git-pack-intersect. It is
used to find redundant packs in git repositories.
Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
---
Makefile | 2
pack-intersect.c | 577 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
sha1_file.c | 3
3 files changed, 581 insertions(+), 1 deletions(-)
create mode 100644 pack-intersect.c
applies-to: bb7dd65e1d945edbe0137a761ebc388c7394067a
cb2f9b435d8101fd29454b77fb5047b7edf847dc
diff --git a/Makefile b/Makefile
index b202be1..4c646c9 100644
--- a/Makefile
+++ b/Makefile
@@ -122,7 +122,7 @@ PROGRAMS = \
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-name-rev$X $(SIMPLE_PROGRAMS)
+ git-name-rev$X git-pack-intersect$X $(SIMPLE_PROGRAMS)
# Backward compatibility -- to be removed after 1.0
PROGRAMS += git-ssh-pull$X git-ssh-push$X
diff --git a/pack-intersect.c b/pack-intersect.c
new file mode 100644
index 0000000..2267478
--- /dev/null
+++ b/pack-intersect.c
@@ -0,0 +1,577 @@
+/*
+*
+* Copyright 2005, Lukas Sandstrom <lukass@etek.chalmers.se>
+*
+* This file is licensed under the GPL v2.
+*
+*/
+
+#include "cache.h"
+
+static const char pack_intersect_usage[] =
+"git-pack-intersect [ -v ] < -a | <.pack filename> ...>";
+
+int all = 0, verbose = 0;
+
+struct llist_item {
+ struct llist_item *next;
+ char *sha1;
+};
+struct llist {
+ struct llist_item *front;
+ struct llist_item *back;
+ size_t size;
+} *all_objects;
+
+struct pack_list {
+ struct pack_list *next;
+ struct packed_git *pack;
+ struct llist *unique_objects;
+ struct llist *all_objects;
+} *pack_list;
+
+struct pll {
+ struct pll *next;
+ struct pack_list *pl;
+};
+
+inline void llist_free(struct llist *list)
+{
+ while((list->back = list->front)) {
+ list->front = list->front->next;
+ free(list->back);
+ }
+ free(list);
+}
+
+inline void llist_init(struct llist **list)
+{
+ *list = xmalloc(sizeof(struct llist));
+ (*list)->front = (*list)->back = NULL;
+ (*list)->size = 0;
+}
+
+struct llist * llist_copy(struct llist *list)
+{
+ struct llist *ret;
+ struct llist_item *new, *old, *prev;
+
+ llist_init(&ret);
+
+ if ((ret->size = list->size) == 0)
+ return ret;
+
+ new = ret->front = xmalloc(sizeof(struct llist_item));
+ new->sha1 = list->front->sha1;
+
+ old = list->front->next;
+ while (old) {
+ prev = new;
+ new = xmalloc(sizeof(struct llist_item));
+ prev->next = new;
+ new->sha1 = old->sha1;
+ old = old->next;
+ }
+ new->next = NULL;
+ ret->back = new;
+
+ return ret;
+}
+
+inline struct llist_item * llist_insert(struct llist *list,
+ struct llist_item *after, char *sha1)
+{
+ struct llist_item *new = xmalloc(sizeof(struct llist_item));
+ new->sha1 = sha1;
+ new->next = NULL;
+
+ if (after != NULL) {
+ new->next = after->next;
+ after->next = new;
+ if (after == list->back)
+ list->back = new;
+ } else {/* insert in front */
+ if (list->size == 0)
+ list->back = new;
+ else
+ new->next = list->front;
+ list->front = new;
+ }
+ list->size++;
+ return new;
+}
+
+inline struct llist_item * llist_insert_back(struct llist *list, char *sha1)
+{
+ return llist_insert(list, list->back, sha1);
+}
+
+inline struct llist_item * llist_insert_sorted_unique(struct llist *list,
+ char *sha1, struct llist_item *hint)
+{
+ struct llist_item *prev = NULL, *l;
+
+ l = (hint == NULL) ? list->front : hint;
+ while (l) {
+ int cmp = memcmp(l->sha1, sha1, 20);
+ if (cmp > 0) { /* we insert before this entry */
+ return llist_insert(list, prev, sha1);
+ }
+ if(!cmp) { /* already exists */
+ return l;
+ }
+ prev = l;
+ l = l->next;
+ }
+ /* insert at the end */
+ return llist_insert_back(list, sha1);
+}
+
+/* computes A\B */
+struct llist * llist_sorted_difference(struct llist_item *A,
+ struct llist_item *B)
+{
+ struct llist *ret;
+ llist_init(&ret);
+
+ while (A != NULL && B != NULL) {
+ int cmp = memcmp(A->sha1, B->sha1, 20);
+ if (!cmp) {
+ A = A->next;
+ B = B->next;
+ continue;
+ }
+ if(cmp > 0) { /* we'll never find this B */
+ B = B->next;
+ continue;
+ }
+ /* A has the object, B doesn't */
+ llist_insert_back(ret, A->sha1);
+ A = A->next;
+ }
+ while (A != NULL) {
+ llist_insert_back(ret, A->sha1);
+ A = A->next;
+ }
+ return ret;
+}
+
+/* returns a pointer to an item in front of sha1 */
+inline struct llist_item * llist_sorted_remove(struct llist *list, char *sha1,
+ struct llist_item *hint)
+{
+ struct llist_item *prev, *l;
+
+redo_from_start:
+ l = (hint == NULL) ? list->front : hint;
+ prev = NULL;
+ while (l) {
+ int cmp = memcmp(l->sha1, sha1, 20);
+ if (cmp > 0) /* not in list, since sorted */
+ return prev;
+ if(!cmp) { /* found */
+ if (prev == NULL) {
+ if (hint != NULL && hint != list->front) {
+ /* we don't know the previous element */
+ hint = NULL;
+ goto redo_from_start;
+ }
+ list->front = l->next;
+ } else
+ prev->next = l->next;
+ if (l == list->back)
+ list->back = prev;
+ free(l);
+ list->size--;
+ return prev;
+ }
+ prev = l;
+ l = l->next;
+ }
+ return prev;
+}
+
+inline struct pack_list * pack_list_insert(struct pack_list **pl,
+ struct pack_list *entry)
+{
+ struct pack_list *p = xmalloc(sizeof(struct pack_list));
+ memcpy(p, entry, sizeof(struct pack_list));
+ p->next = *pl;
+ *pl = p;
+ return p;
+}
+
+struct pack_list * pack_list_difference(struct pack_list *A,
+ struct pack_list *B)
+{
+ struct pack_list *ret, *pl;
+
+ if (A == NULL)
+ return NULL;
+
+ pl = B;
+ while (pl != NULL) {
+ if (A->pack == pl->pack)
+ return pack_list_difference(A->next, B);
+ pl = pl->next;
+ }
+ ret = xmalloc(sizeof(struct pack_list));
+ memcpy(ret, A, sizeof(struct pack_list));
+ ret->next = pack_list_difference(A->next, B);
+ return ret;
+}
+
+void cmp_two_packs(struct pack_list *p1, struct pack_list *p2)
+{
+ int p1_off, p2_off;
+ void *p1_base, *p2_base;
+ struct llist_item *p1_hint = NULL, *p2_hint = NULL;
+
+ p1_off = p2_off = 256 * 4 + 4;
+ p1_base = (void *)p1->pack->index_base;
+ p2_base = (void *)p2->pack->index_base;
+
+ while (p1_off <= p1->pack->index_size - 3 * 20 &&
+ p2_off <= p2->pack->index_size - 3 * 20)
+ {
+ int cmp = memcmp(p1_base + p1_off, p2_base + p2_off, 20);
+ /* cmp ~ p1 - p2 */
+ if (cmp == 0) {
+ p1_hint = llist_sorted_remove(p1->unique_objects,
+ p1_base + p1_off, p1_hint);
+ p2_hint = llist_sorted_remove(p2->unique_objects,
+ p1_base + p1_off, p2_hint);
+ p1_off+=24;
+ p2_off+=24;
+ continue;
+ }
+ if (cmp < 0) { /* p1 has the object, p2 doesn't */
+ p1_off+=24;
+ } else { /* p2 has the object, p1 doesn't */
+ p2_off+=24;
+ }
+ }
+}
+
+/* all the permutations have to be free()d at the same time,
+ * since they refer to each other
+ */
+struct pll * get_all_permutations(struct pack_list *list)
+{
+ struct pll *subset, *pll, *new_pll = NULL; /*silence warning*/
+
+ if (list == NULL)
+ return NULL;
+
+ if (list->next == NULL) {
+ new_pll = xmalloc(sizeof(struct pll));
+ new_pll->next = NULL;
+ new_pll->pl = list;
+ return new_pll;
+ }
+
+ pll = subset = get_all_permutations(list->next);
+ while (pll) {
+ new_pll = xmalloc(sizeof(struct pll));
+ new_pll->next = pll->next;
+ pll->next = new_pll;
+
+ new_pll->pl = xmalloc(sizeof(struct pack_list));
+ memcpy(new_pll->pl, list, sizeof(struct pack_list));
+ new_pll->pl->next = pll->pl;
+
+ pll = new_pll->next;
+ }
+ /* add ourself to the end */
+ new_pll->next = xmalloc(sizeof(struct pll));
+ new_pll->next->pl = xmalloc(sizeof(struct pack_list));
+ new_pll->next->next = NULL;
+ memcpy(new_pll->next->pl, list, sizeof(struct pack_list));
+ new_pll->next->pl->next = NULL;
+
+ return subset;
+}
+
+int is_superset(struct pack_list *pl, struct llist *list)
+{
+ struct llist *diff, *old;
+
+ diff = llist_copy(list);
+
+ while (pl) {
+ old = diff;
+ diff = llist_sorted_difference(diff->front,
+ pl->all_objects->front);
+ llist_free(old);
+ if (diff->size == 0) { /* we're done */
+ llist_free(diff);
+ return 1;
+ }
+ pl = pl->next;
+ }
+ llist_free(diff);
+ return 0;
+}
+
+size_t sizeof_union(struct packed_git *p1, struct packed_git *p2)
+{
+ size_t ret = 0;
+ int p1_off, p2_off;
+ void *p1_base, *p2_base;
+
+ p1_off = p2_off = 256 * 4 + 4;
+ p1_base = (void *)p1->index_base;
+ p2_base = (void *)p2->index_base;
+
+ while (p1_off <= p1->index_size - 3 * 20 &&
+ p2_off <= p2->index_size - 3 * 20)
+ {
+ int cmp = memcmp(p1_base + p1_off, p2_base + p2_off, 20);
+ /* cmp ~ p1 - p2 */
+ if (cmp == 0) {
+ ret++;
+ p1_off+=24;
+ p2_off+=24;
+ continue;
+ }
+ if (cmp < 0) { /* p1 has the object, p2 doesn't */
+ p1_off+=24;
+ } else { /* p2 has the object, p1 doesn't */
+ p2_off+=24;
+ }
+ }
+ return ret;
+}
+
+/* another O(n^2) function ... */
+size_t get_pack_redundancy(struct pack_list *pl)
+{
+ struct pack_list *subset;
+ size_t ret = 0;
+ while ((subset = pl->next)) {
+ while(subset) {
+ ret += sizeof_union(pl->pack, subset->pack);
+ subset = subset->next;
+ }
+ pl = pl->next;
+ }
+ return ret;
+}
+
+inline size_t pack_set_bytecount(struct pack_list *pl)
+{
+ size_t ret = 0;
+ while (pl) {
+ ret += pl->pack->pack_size;
+ ret += pl->pack->index_size;
+ pl = pl->next;
+ }
+ return ret;
+}
+
+void minimize(struct pack_list **min)
+{
+ struct pack_list *pl, *unique = NULL,
+ *non_unique = NULL, *min_perm = NULL;
+ struct pll *perm, *perm_all, *perm_ok = NULL, *new_perm;
+ struct llist *missing, *old;
+ size_t min_perm_size = (size_t)-1, perm_size;
+
+ pl = pack_list;
+ while (pl) {
+ if(pl->unique_objects->size)
+ pack_list_insert(&unique, pl);
+ else
+ pack_list_insert(&non_unique, pl);
+ pl = pl->next;
+ }
+ /* find out which objects are missing from the set of unique packs */
+ missing = llist_copy(all_objects);
+ pl = unique;
+ while (pl) {
+ old = missing;
+ missing = llist_sorted_difference(missing->front,
+ pl->all_objects->front);
+ llist_free(old);
+ pl = pl->next;
+ }
+
+ if (missing->size == 0) {
+ *min = unique;
+ return;
+ }
+
+ /* find the permutations which contain all missing objects */
+ perm_all = perm = get_all_permutations(non_unique);
+ while (perm) {
+ if (is_superset(perm->pl, missing)) {
+ new_perm = xmalloc(sizeof(struct pll));
+ new_perm->pl = perm->pl;
+ new_perm->next = perm_ok;
+ perm_ok = new_perm;
+ }
+ perm = perm->next;
+ }
+
+ if (perm_ok == NULL)
+ die("Internal error: No complete sets found!\n");
+
+ /* find the permutation with the smallest size */
+ perm = perm_ok;
+ while (perm) {
+ perm_size = pack_set_bytecount(perm->pl);
+ if (min_perm_size > perm_size) {
+ min_perm_size = perm_size;
+ min_perm = perm->pl;
+ }
+ perm = perm->next;
+ }
+ *min = min_perm;
+ /* add the unique packs to the list */
+ pl = unique;
+ while(pl) {
+ pack_list_insert(min, pl);
+ pl = pl->next;
+ }
+}
+
+void load_all_objects()
+{
+ struct pack_list *pl = pack_list;
+ struct llist_item *hint, *l;
+ int i;
+
+ llist_init(&all_objects);
+
+ while (pl) {
+ i = 0;
+ hint = NULL;
+ l = pl->all_objects->front;
+ while (l) {
+ hint = llist_insert_sorted_unique(all_objects,
+ l->sha1, hint);
+ l = l->next;
+ }
+ pl = pl->next;
+ }
+}
+
+/* this scales like O(n^2) */
+void cmp_packs()
+{
+ struct pack_list *subset, *curr = pack_list;
+
+ while ((subset = curr)) {
+ while((subset = subset->next))
+ cmp_two_packs(curr, subset);
+ curr = curr->next;
+ }
+}
+
+struct pack_list * add_pack(struct packed_git *p)
+{
+ struct pack_list l;
+ size_t off;
+ void *base;
+
+ l.pack = p;
+ llist_init(&l.all_objects);
+
+ off = 256 * 4 + 4;
+ base = (void *)p->index_base;
+ while (off <= p->index_size - 3 * 20) {
+ llist_insert_back(l.all_objects, base + off);
+ off+=24;
+ }
+ /* this list will be pruned in cmp_two_packs later */
+ l.unique_objects = llist_copy(l.all_objects);
+ return pack_list_insert(&pack_list, &l);
+}
+
+struct pack_list * add_pack_file(char *filename)
+{
+ struct packed_git *p = packed_git;
+
+ if (strlen(filename) < 40)
+ die("Bad pack filename: %s\n", filename);
+
+ while (p) {
+ if (strstr(p->pack_name, filename))
+ /* this will silently ignore packs in alt-odb */
+ return add_pack(p);
+ p = p->next;
+ }
+ die("Filename %s not found in packed_git\n", filename);
+}
+
+void load_all()
+{
+ struct packed_git *p = packed_git;
+
+ while (p) {
+ if (p->pack_local) /* ignore alt-odb for now */
+ add_pack(p);
+ p = p->next;
+ }
+}
+
+int main(int argc, char **argv)
+{
+ int i;
+ struct pack_list *min, *red, *pl;
+
+ for (i = 1; i < argc; i++) {
+ const char *arg = argv[i];
+ if(!strcmp(arg, "--"))
+ break;
+ if(!strcmp(arg, "-a")) {
+ all = 1;
+ continue;
+ }
+ if(!strcmp(arg, "-v")) {
+ verbose = 1;
+ continue;
+ }
+ if(*arg == '-')
+ usage(pack_intersect_usage);
+ else
+ break;
+ }
+
+ prepare_packed_git();
+
+ if(all)
+ load_all();
+ else
+ while (*(argv + i) != NULL)
+ add_pack_file(*(argv + i++));
+
+ if (pack_list == NULL)
+ die("Zero packs found!\n");
+
+ cmp_packs();
+
+ load_all_objects();
+
+ minimize(&min);
+ if (verbose) {
+ fprintf(stderr, "The smallest (bytewise) set of packs is:\n");
+ pl = min;
+ while (pl) {
+ fprintf(stderr, "\t%s\n", pl->pack->pack_name);
+ pl = pl->next;
+ }
+ fprintf(stderr, "containing %ld duplicate objects "
+ "with a total size of %ldkb.\n",
+ get_pack_redundancy(min), pack_set_bytecount(min)/1024);
+ fprintf(stderr, "Redundant packs (with indexes):\n");
+ }
+ pl = red = pack_list_difference(pack_list, min);
+ while (pl) {
+ printf("%s\n%s\n",
+ sha1_pack_index_name(pl->pack->sha1), pl->pack->pack_name);
+ pl = pl->next;
+ }
+
+ return 0;
+}
diff --git a/sha1_file.c b/sha1_file.c
index 946a353..cd814d7 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -424,6 +424,7 @@ struct packed_git *add_packed_git(char *
struct packed_git *p;
unsigned long idx_size;
void *idx_map;
+ char sha1[20];
if (check_packed_git_idx(path, &idx_size, &idx_map))
return NULL;
@@ -447,6 +448,8 @@ struct packed_git *add_packed_git(char *
p->pack_last_used = 0;
p->pack_use_cnt = 0;
p->pack_local = local;
+ if (!get_sha1_hex(path + path_len - 40 - 4, sha1))
+ memcpy(p->sha1, sha1, 20);
return p;
}
---
0.99.9.GIT
^ permalink raw reply related
* [PATCH 0/4] Add git-pack-intersect
From: Lukas Sandström @ 2005-11-09 1:20 UTC (permalink / raw)
To: git; +Cc: junkio, Lukas Sandström
This patch series adds git-pack-intersect. It finds redundant packs
by calculating the union of all objects present in .git/objects/pack
and then computing the smallest set of packs which contain all the
objects in this union.
It is quite fast, if I may say so myself. On my AMD3200+ it manages
to minimize a linux-2.6 repository with 9 pack files totaling 430MB
in ~0.7 seconds. The remaining packfiles total 102MB, which is a nice
reduction.
git-fsck-objects reports no errors after pruning, but the algorithm is
not proven correct so backups might be in order before this gets more
testing.
/Lukas
^ permalink raw reply
* Re: Errors cloning over http -- git-clone and cg-clone fail to fetch a reachable object...
From: Nick Hengeveld @ 2005-11-09 1:09 UTC (permalink / raw)
To: Ben Clifford; +Cc: Martin Langhoff, Git Mailing List
In-Reply-To: <1537CD60-21E4-4F5E-820F-216A4E8C06AC@hawaga.org.uk>
On Tue, Nov 08, 2005 at 10:19:53PM +1100, Ben Clifford wrote:
> I got similar today; www.hawaga.org.uk is some apache server on
> linux, and piva.hawaga.org.uk, the client Mac OS X.
> ...
> error: (curl_result = 3181280, http_code = 200, sha1 =
> c99aa418704f576aad8249d042cd6afecf38afc4)
Those curl result codes all look wrong, and sounds like a memory issue
that Johannes Schindelin recently fixed in commit
90279074ca5cc336a8bfffd47d19d089b291b432. Does your git build have that
patch?
--
For a successful technology, reality must take precedence over public
relations, for nature cannot be fooled.
^ permalink raw reply
* Re: Comments on recursive merge..
From: Junio C Hamano @ 2005-11-09 0:59 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0511081646160.3247@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> Junio? You even wrote the comment about the case in git-merge-base, I'm
> wondering whether it's a bug that we use the fast-and-cheap algorithm in
> git-show-branch..
I did show-branch soon after we worked on those pathlogical
merge-base fix, so I would be a bit surprised if I did it
without using all the knowledge from that exercise, but I do not
remember offhand. The core logic should be simple
generalization of two-head merge-base to N heads.
^ permalink raw reply
* Re: Comments on recursive merge..
From: Linus Torvalds @ 2005-11-09 0:51 UTC (permalink / raw)
To: Petr Baudis; +Cc: Fredrik Kuivinen, Johannes Schindelin, Junio C Hamano, git
In-Reply-To: <20051109003236.GA30496@pasky.or.cz>
On Wed, 9 Nov 2005, Petr Baudis wrote:
>
> BTW, git-show-branch is also by orders of magnitude faster (not that
> this would be any major timesaver). Median 0.006s vs. median 0.124s.
Ouch. That makes me suspicious. One reason git-merge-base is slow is
because it's being pretty careful about some pathological examples of
dates being just the wrong way around, and it might just be that the
reason git-show-branch is faster is because it isn't doing that part
right.
So yes, git-merge-base does extra work, but it does so because I think it
needs to.
Junio? You even wrote the comment about the case in git-merge-base, I'm
wondering whether it's a bug that we use the fast-and-cheap algorithm in
git-show-branch..
Of course, arguably you can first try the fast-and-cheap thing, and if
that gives a merge parent that is acceptable, why not? So maybe it's the
right thing for the "let's see if this is trivial" case, but I think it
might _think_ some cases are trivial that really shouldn't, because they
actually have two merge parents.
Linus
^ permalink raw reply
* Re: Comments on recursive merge..
From: Petr Baudis @ 2005-11-09 0:32 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Fredrik Kuivinen, Johannes Schindelin, Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0511081450080.3247@g5.osdl.org>
Dear diary, on Wed, Nov 09, 2005 at 12:05:43AM CET, I got a letter
where Linus Torvalds <torvalds@osdl.org> said that...
> Junio, that points out that "git-merge-base" is another program that could
> just be removed, since it's really supreceded by git-show-branch. Or did I
> miss something?
Wow, I didn't know git-show-branch could do that (even though it's a bit
unnatural to expect this from command named this way; then again,
there's git-rev-parse...).
BTW, git-show-branch is also by orders of magnitude faster (not that
this would be any major timesaver). Median 0.006s vs. median 0.124s.
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.
^ permalink raw reply
* Re: Errors cloning over http -- git-clone and cg-clone fail to fetch a reachable object...
From: Ben Clifford @ 2005-11-08 11:19 UTC (permalink / raw)
To: Martin Langhoff, Nick Hengeveld, Git Mailing List
In-Reply-To: <46a038f90511061354k5378a92ckc427841f90ec8b4@mail.gmail.com>
I got similar today; www.hawaga.org.uk is some apache server on
linux, and piva.hawaga.org.uk, the client Mac OS X.
Feel free to hit the URL yourselves -- its a public webserver.
According to system profiler on piva:
System Version: Mac OS X 10.4.2 (8D37)
Kernel Version: Darwin 8.2.1
and
!582 [1] benc@piva:~/tmp$ curl --version
curl 7.13.1 (powerpc-apple-darwin8.0) libcurl/7.13.1 OpenSSL/0.9.7g
zlib/1.2.3
Protocols: ftp gopher telnet dict ldap http file https ftps
Features: IPv6 Largefile NTLM SSL libz
!583 [1] benc@piva:~/tmp$
This is on an unpacked repository, so I would guess that none of the
GETs for objects should be failing...
Note that it *doesn't* always error out on the same object:
!549 [0] benc@piva:~/tmp$ cg clone http://www.hawaga.org.uk/
gitcompletion.gitdefaulting to local storage area
20:56:33 URL:http://www.hawaga.org.uk/gitcompletion.git/HEAD [41/41] -
> "refs/heads/.origin-fetching" [1]
progress: 11 objects, 2875 bytes
error: (curl_result = 3181280, http_code = 200, sha1 =
c99aa418704f576aad8249d042cd6afecf38afc4)
Getting pack list
error:
Getting alternates list
error: Unable to find c99aa418704f576aad8249d042cd6afecf38afc4 under
http://www.hawaga.org.uk/gitcompletion.git/
Cannot obtain needed blob c99aa418704f576aad8249d042cd6afecf38afc4
while processing commit 912eb2baf57b70178c2e1f10df12eae911e1d748.
cg-fetch: objects fetch failed
cg-clone: fetch failed
!550 [0] benc@piva:~/tmp$
!556 [0] benc@piva:~/tmp$ cg clone http://www.hawaga.org.uk/
gitcompletion.git
defaulting to local storage area
20:58:48 URL:http://www.hawaga.org.uk/gitcompletion.git/HEAD [41/41] -
> "refs/heads/.origin-fetching" [1]
progress: 12 objects, 4581 bytes
error: (curl_result = 3179088, http_code = 200, sha1 =
682cfbd4d75e204fada2cabe9e0f040e522ce61d)
Getting pack list
Getting alternates list
error: Unable to find 682cfbd4d75e204fada2cabe9e0f040e522ce61d under
http://www.hawaga.org.uk/gitcompletion.git/
Cannot obtain needed commit 682cfbd4d75e204fada2cabe9e0f040e522ce61d
while processing commit 912eb2baf57b70178c2e1f10df12eae911e1d748.
Waiting for http://www.hawaga.org.uk/gitcompletion.git/objects/cb/
c8285a736142b83894ec412fe413d9ee7363ab
cg-fetch: objects fetch failed
cg-clone: fetch failed
!557 [0] benc@piva:~/tmp$
When I run it lots of times in succession, it gets between 10 and 15
objects in before failing on something.
When I try with plain git:
!580 [1] benc@piva:~/tmp$ git clone http://www.hawaga.org.uk/
gitcompletion.git here
defaulting to local storage area
got a108bdc110dad770ec5c092759a8bc511790d21f
walk a108bdc110dad770ec5c092759a8bc511790d21f
got 912eb2baf57b70178c2e1f10df12eae911e1d748
got 261466f44dce8fb3cac4e0d0f1bf5a46fa84e07e
walk 912eb2baf57b70178c2e1f10df12eae911e1d748
got f766b276eff3ec52ac3c0425b13c936d87c607ee
got e05988e4a193f9eac2862ce6e67b19e3785bd8f1
got c99aa418704f576aad8249d042cd6afecf38afc4
got d743b178b82e9a8f10a1bf267d32d070e36c8046
got 96a0d6b6b182d978c04290f7c87049a5d3cc41b7
got 676bd846066cf3794796cadb258a23a76744819c
got 2e04450bdc81b1380a8f75223d8ce8019400dd70
error: (curl_result = 3179232, http_code = 200, sha1 =
682cfbd4d75e204fada2cabe9e0f040e522ce61d)
Getting pack list
error:
Getting alternates list
error: Unable to find 682cfbd4d75e204fada2cabe9e0f040e522ce61d under
http://www.hawaga.org.uk/gitcompletion.git/
Cannot obtain needed commit 682cfbd4d75e204fada2cabe9e0f040e522ce61d
while processing commit 912eb2baf57b70178c2e1f10df12eae911e1d748.
!581 [1] benc@piva:~/tmp$
but a curl by hand for one of the object URLs works:
!581 [1] benc@piva:~/tmp$ curl http://www.hawaga.org.uk/
gitcompletion.git/objects/68/2cfbd4d75e204fada2cabe9e0f040e522ce61d
> /dev/null
% Total % Received % Xferd Average Speed Time Time
Time Current
Dload Upload Total Spent
Left Speed
100 250 100 250 0 0 183 0 0:00:01 0:00:01
--:--:-- 0
!582 [1] benc@piva:~/tmp$
and works each time when I run it repeatedly.
On 7 Nov 2005, at 08:54, Martin Langhoff wrote:
> Strange!
>
> I'm getting errors when cloning over http
>
> git-clone http://locke.catalyst.net.nz/git/moodle.git mdlfoo
> (...)
> error: (curl_result = 3601440, http_code = 200, sha1 =
> f04241b142edfbf28fff2babb426cbab5b44e26b)
> Getting pack list
> error:
> Getting alternates list
> error: Unable to find f04241b142edfbf28fff2babb426cbab5b44e26b under
> http://locke.catalyst.net.nz/git/moodle.git/
>
> Cannot obtain needed commit f04241b142edfbf28fff2babb426cbab5b44e26b
> while processing commit 0965f28d4d75f324b86c8f7490830fea471c65c5.
>
> This commit object is easily reachable at
> http://mirrors.catalyst.net.nz/git/moodle.git/objects/
> f0/4241b142edfbf28fff2babb426cbab5b44e26b
>
> If I use cg-clone, I get a similar error
>
> cg-clone http://locke.catalyst.net.nz/git/moodle.git#mdl-artena-
> tairawhiti
> mdlfooo
> (...)
> Cannot obtain needed object 214e6374d49e6d014f0ba6f159d585a3fe468909
> while processing commit 0000000000000000000000000000000000000000.
> cg-fetch: objects fetch failed
> cg-clone: fetch failed
>
> This commit object seems to be in a pack:
> http://mirrors.catalyst.net.nz/git/moodle.git/objects/pack/
> pack-094560c0177ad659a6e172739c4be53da749e5f0.pack
>
> git-cat-file on the server works correctly, and cloning/working over
> git+ssh works too.
>
> cheers,
>
>
> martin
> -
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
>
--
Ben ベン Бэн
http://www.hawaga.org.uk/ben/
^ permalink raw reply
* Re: Comments on recursive merge..
From: Linus Torvalds @ 2005-11-09 0:18 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Fredrik Kuivinen, Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.63.0511090017370.28256@wbgn013.biozentrum.uni-wuerzburg.de>
On Wed, 9 Nov 2005, Johannes Schindelin wrote:
>
> On Tue, 8 Nov 2005, Linus Torvalds wrote:
>
> > Junio, that points out that "git-merge-base" is another program that could
> > just be removed, since it's really supreceded by git-show-branch. Or did I
> > miss something?
>
> IIRC, git-show-branch has a limit on the number of refs it can take.
Well, git-merge-base does too. git-merge-base only takes two refs ;)
In general, you need to keep track of one bit per ref, and since we have
a 32-bit "flags" word and need a couple of bits for other maintenance
info, pretty much anything that figures out common heads will be limited
some way.
This is only a limit for the "and" logic - the "or" logic (if we implement
it) will just share the same status bit for all the refs that are "ored
together" and thus has no limits.
Oh, and the "and" logic can be extended by running the program multiple
times, so it's not a "hard" limit, it's just an issue of convenience.
That said, anybody who ever does an octopus of more than just a few heads
deserves to be shot, so I don't think the limit should matter. The
recursive strategy should only add the "or" kind of refs, and it
shouldn't be a problem (apart from just how to describe them).
Linus
^ permalink raw reply
* [cogito] cg-merge does not remove files removed upstream on fast-forward
From: Blaisorblade @ 2005-11-09 0:08 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
Once again, (not the first time) when doing "cg-merge origin" (or cg-update I
guess, too) I find a tons of files which were removed upstream and cogito
didn't remove. It was a fast-forward merge on Linus' tree:
$ cg merge origin
Fast-forwarding d83c671fb7023f69a9582e622d01525054f23b66 ->
a52e8381c430896d3bd6065a34fda99cb5c74c82
on top of d83c671fb7023f69a9582e622d01525054f23b66...
cg version
cogito-0.15.1 (b07f98ba4cabdd9d208da28be932e547675e5cdf)
(The base id is ab91bd11258f8987fc8d537871c733e04f8c8248, I've added a trivial
patch to add more options to cg-diff and cg-mkpatch, i.e. unrelated).
Below there is the excerpt of code in tree_timewarp:
# Kill gone files
git-diff-tree -z -r $base $branch | xargs -0 bash -c '
while [ "$1" ]; do
header="$1"; shift
file="$1"; shift
# match ":100755 000000 14d43b1abf... 000000000... D"
if echo "$header" | egrep "^:([^ ][^ ]* ){4}D"
>/dev/null; then
rm -- "$file"
fi
done
' padding
I must say I also saw git-ls-files --deleted running with top (probably from
cg-patch), but it didn't seem to help.
--
Inform me of my mistakes, so I can keep imitating Homer Simpson's "Doh!".
Paolo Giarrusso, aka Blaisorblade (Skype ID "PaoloGiarrusso", ICQ 215621894)
http://www.user-mode-linux.org/~blaisorblade
___________________________________
Yahoo! Messenger: chiamate gratuite in tutto il mondo
http://it.messenger.yahoo.com
^ permalink raw reply
* Re: Diff between the non-head git work dir and non-git kernel sources
From: lamikr @ 2005-11-08 23:52 UTC (permalink / raw)
To: git
In-Reply-To: <7vacgeeqb3.fsf@assigned-by-dhcp.cox.net>
Junio, thanks for the help, I think the problems are now vanished :-)
Junio C Hamano wrote:
>lamikr <lamikr@cc.jyu.fi> writes:
>
>Let me understand what trees are involved. I am not sure from
>your description.
>
> 1. You based your own development on some kernel snapshot.
>
> 2. The kernel snapshot you based 1. is "some version".
>
> 3. Mvista has d24aff0b commit that contains their changes to
> a kernel snapshot (the same "some version" as 2).
>
> 4. Mvista now has different version, descendant of 3. This is
> the top of omap tree you cloned.
>
> --------------------------->[2] yours
> /
> [1]------------->[3]----------->[4] omap tip
>
>Is this the commit history graph you have?
>
>
Almost like this.
a) I used 2.6.14-rc5.tar.bz2 as a base
b) Then I applied
2.6.14-rc5.tar.bz2 and
http://www.muru.com/linux/omap/patches/patch-2.6.14-rc5-omap1.bz2
on top of that. This is a snapshot from the OMAP git tree. [1]
c) I merged my own development to these sources --> [2]
d) I manually applied all patches released to omap tree between
patch-2.6.14-rc5-omap1.bz2 and
commit-id d24aff0bd3e788d69a45a9d1b1eecda88d847a41 --> [5]
So the relation between kernel version [5] that I have in non git tree
is basically following and current omap git tree is
following kind.
---my changes-->[2]----->[5] my source tree (non git)
/ /
[1]----------------------->[3]---------->[4] omap git (currently in 2.6.14 level)
I needed to change git working directory from state [4] to state [3] so
that I could create the
diff between [3] and [5]. (And then try to merge it back on top of [4]...)
>>I would now like to revert the sources in git working dir to state that
>>was after this d24aff0bd3e788d69a45a9d1b1eecda88d847a41 commit
>>and then make the diff between that kernel source version and my non-git
>>source version.
>>
>>
>
>You lost me here. Presumably the ultimate goal of what you are
>doing is either one of the following:
>
>(1) port your good changes between [1] and [2] on top of [4], or
>
>
Yes, my goal is to have in future a own local git branch that follows
mvistas git tree.
(and mvistas tree follows mainline) For this I have found good looking
documentation.
>(2) port progresses in omap tree between [3] and [4] (or perhaps
> [1] and [4], including changes betwen [1] and [3]) on top of
> your tree [2].
>
>But I am not sure what you mean by the above paragraph. You
>sound as if you want to find out the differences between [3]
>("revert it to d24aff") and [2] ("your non-git source").
>
>If that is what you want instead, assuming you have your kernel
>tree in linux-lamikr and omap tree in linux-omap:
>
> $ cd linux-omap
> $ git checkout -b snapshot-d24aff0b d24aff0b
>
>
This was the thing I wanted to know and it worked. I made something
wrong in my own attempts and I always failed to revert to own version.
(Propaply because I tried to create tag names)
>Another possibility would be to move your development to .git;
>if you know the commit id of [1], then you can branch from that
>commit and replay your development trail step by step up to [2].
>This obviously requires that you used some SCM to keep track
>your development trail between [1] and [2].
>
>Once you have done that (and assuming your branch is called
>lamikr), you could compare omap and your tip with:
>
> $ git checkout lamikr
> $ git diff lamikr origin
>
>Or even merge omap tip into your branch:
>
> $ git checkout lamikr
> $ git pull . origin
>
>all inside linux-omap/ directory.
>
>
Well, I already started diff running in the background by using the
first solution but I will also try this one for the comparison.
Mika
^ permalink raw reply
* [PATCH] Update howto using-topic-branches
From: Luck, Tony @ 2005-11-08 23:52 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
"git resolve" is being deprecated in favour of "git merge".
Update the documentation to reflect this.
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
Untested ... I'll update my real scripts to do it this way soon.
diff --git a/Documentation/howto/using-topic-branches.txt b/Documentation/howto/using-topic-branches.txt
index c6c635a..4698abe 100644
--- a/Documentation/howto/using-topic-branches.txt
+++ b/Documentation/howto/using-topic-branches.txt
@@ -9,7 +9,7 @@ GIT as a Linux subsystem maintainer.
-Tony
-Last updated w.r.t. GIT 0.99.5
+Last updated w.r.t. GIT 0.99.9f
Linux subsystem maintenance using GIT
-------------------------------------
@@ -89,8 +89,8 @@ out at the current tip of the linus bran
These can be easily kept up to date by merging from the "linus" branch:
- $ git checkout test && git resolve test linus "Auto-update from upstream"
- $ git checkout release && git resolve release linus "Auto-update from upstream"
+ $ git checkout test && git merge "Auto-update from upstream" test linus
+ $ git checkout release && git merge "Auto-update from upstream" release linus
Set up so that you can push upstream to your public tree (you need to
log-in to the remote system and create an empty tree there before the
@@ -128,7 +128,7 @@ commit to this branch.
When you are happy with the state of this change, you can pull it into the
"test" branch in preparation to make it public:
- $ git checkout test && git resolve test speed-up-spinlocks "Pull speed-up-spinlock changes"
+ $ git checkout test && git merge "Pull speed-up-spinlock changes" test speed-up-spinlocks
It is unlikely that you would have any conflicts here ... but you might if you
spent a while on this step and had also pulled new versions from upstream.
@@ -138,7 +138,7 @@ same branch into the "release" tree read
see the value of keeping each patch (or patch series) in its own branch. It
means that the patches can be moved into the "release" tree in any order.
- $ git checkout release && git resolve release speed-up-spinlocks "Pull speed-up-spinlock changes"
+ $ git checkout release && git merge "Pull speed-up-spinlock changes" release speed-up-spinlocks
After a while, you will have a number of branches, and despite the
well chosen names you picked for each of them, you may forget what
@@ -190,7 +190,7 @@ Here are some of the scripts that I use
case "$1" in
test|release)
- git checkout $1 && git resolve $1 linus "Auto-update from upstream"
+ git checkout $1 && git merge "Auto-update from upstream" $1 linus
;;
linus)
before=$(cat .git/refs/heads/linus)
@@ -231,7 +231,7 @@ test|release)
echo $1 already merged into $2 1>&2
exit 1
fi
- git checkout $2 && git resolve $2 $1 "Pull $1 into $2 branch"
+ git checkout $2 && git merge "Pull $1 into $2 branch" $2 $1
;;
*)
usage
^ permalink raw reply related
* Re: Comments on recursive merge..
From: Johannes Schindelin @ 2005-11-08 23:18 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Fredrik Kuivinen, Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0511081450080.3247@g5.osdl.org>
Hi,
On Tue, 8 Nov 2005, Linus Torvalds wrote:
> Junio, that points out that "git-merge-base" is another program that could
> just be removed, since it's really supreceded by git-show-branch. Or did I
> miss something?
IIRC, git-show-branch has a limit on the number of refs it can take.
Ciao,
Dscho
^ permalink raw reply
* Re: Comments on recursive merge..
From: Linus Torvalds @ 2005-11-08 23:05 UTC (permalink / raw)
To: Fredrik Kuivinen; +Cc: Johannes Schindelin, Junio C Hamano, git
In-Reply-To: <20051108223609.GA4805@c165.ib.student.liu.se>
On Tue, 8 Nov 2005, Fredrik Kuivinen wrote:
>
> The problem is in the multiple-common-ancestors case. If we have three
> common ancestors, A, B and C, we will start with merging A with B. The
> result is a new 'virtual' commit object (not stored in the object
> database), lets call it V. We are then going to merge V with C. To do
> that we need to get the common ancestor(s) of V and C, and as V
> doesn't exist in the database we can't use git-merge-base.
Hmm. That's really the same as the merge-base of "C _and_ (A _or_ B)",
isn't it?
So we should be able to do that even without ever seeing the virtual
merge. In fact, it really is pretty trivial from a technical standpoint:
the "A _or_ B" part is really just inserting both A and B with the same
"flags" value (see the "merge_base()" function in merge-base.c).
So in general, "merge-base" could trivially be extended to have any number
of "OR commits" on either side, as long as there is just one "and".
It could also be extended to have multiple "and" cases, but that has
actually already been done by "git-show-branch", I think. It's all the
same logic, except it uses more than just two bits.
So _technically_ it should be easy to do, it would just need some sane
command line syntax to specify the grouping.
> I haven't given it a lot of thought though, it might be possible to
> use git-merge-base in some way and get the same results as we get now.
>
> It would certainly be possible to use git-merge-base in the first
> iteration and use the python code only when we actually have any
> 'virtual' commit objects.
Just handling the first case specially would be sufficient for 99% of all
uses. And if the multi-parent cases are slightly slower, I don't think
anybody cares.
In fact, we _always_ do the first git-merge-base in git-merge.sh anyway
(actually, not git-merge-base, but "git-show-branch --merge-base"). So
that's really done already for the "test if it's trivial" case..
Junio, that points out that "git-merge-base" is another program that could
just be removed, since it's really supreceded by git-show-branch. Or did I
miss something?
Linus
^ permalink raw reply
* Re: Comments on recursive merge..
From: Johannes Schindelin @ 2005-11-08 23:04 UTC (permalink / raw)
To: Fredrik Kuivinen; +Cc: Linus Torvalds, Junio C Hamano, git
In-Reply-To: <20051108210211.GA23265@c165.ib.student.liu.se>
Hi,
On Tue, 8 Nov 2005, Fredrik Kuivinen wrote:
> On Tue, Nov 08, 2005 at 12:58:50PM +0100, Johannes Schindelin wrote:
> >
> > We already have a fallback list: after really-trivial, try automatic, ...,
> > try resolve. Why not just add recursive? So, if even resolve failed, just
> > try once more, with recursive.
> >
>
> I don't think this is a very good idea for two reasons. The first one
> is that there are some merge scenarios involving renames which should
> be conflicts but are cleanly merged by git-resolve.
>
> The second reason is that with the fall back list the recursive
> strategy will only be used in the strange corner cases and will thus
> not get nearly the same amount of testing it would get if it was the
> first choice (or directly after the really-trivial merge).
Two very valid points. You convinced me.
Ciao,
Dscho
^ permalink raw reply
* Re: Expected Behavior?
From: Fredrik Kuivinen @ 2005-11-08 22:53 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Fredrik Kuivinen, Jon Loeliger, git
In-Reply-To: <7v7jbig6m7.fsf@assigned-by-dhcp.cox.net>
On Tue, Nov 08, 2005 at 01:41:20PM -0800, Junio C Hamano wrote:
> Fredrik Kuivinen <freku045@student.liu.se> writes:
>
> > Jon: You could try to this merge with the recursive merge strategy
> > (git merge -s recursive 'merge message' master dev) If you do, you
> > _should_ get something like:
> >
> > CONFLICT (add/add): File file3 added non-identically in both
> > branches. Adding as file3_master and file3_dev instead.
> >
> > You will then end up with file3_master and file3_dev in your working
> > tree, which corresponds to file3 in the master branch and file3 in the
> > dev branch, respectively.
>
> Oops, I missed that part. This is unsafe in theory, if you
> could overwrite existing file3_master or file3_dev. Does that
> matter in practice?
>
It wont overwrite any existing files. If there is a file named
'file3_master' then the new file will be named 'file3_master_1' and if
that file also exists the new file will be named 'file3_master_2', and
so on.
- Fredrik
^ permalink raw reply
* Re: Comments on recursive merge..
From: Fredrik Kuivinen @ 2005-11-08 22:36 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Fredrik Kuivinen, Johannes Schindelin, Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0511081351020.3247@g5.osdl.org>
On Tue, Nov 08, 2005 at 01:52:06PM -0800, Linus Torvalds wrote:
>
>
> On Tue, 8 Nov 2005, Fredrik Kuivinen wrote:
> >
> > * The code for finding common ancestors is also written in Python and
> > is probably a bit slower than git-merge-base.
>
> Btw, what part of git-merge-bases is it that makes it not be practical?
>
The problem is in the multiple-common-ancestors case. If we have three
common ancestors, A, B and C, we will start with merging A with B. The
result is a new 'virtual' commit object (not stored in the object
database), lets call it V. We are then going to merge V with C. To do
that we need to get the common ancestor(s) of V and C, and as V
doesn't exist in the database we can't use git-merge-base.
I haven't given it a lot of thought though, it might be possible to
use git-merge-base in some way and get the same results as we get now.
It would certainly be possible to use git-merge-base in the first
iteration and use the python code only when we actually have any
'virtual' commit objects.
- Fredrik
^ permalink raw reply
* Re: Diff between the non-head git work dir and non-git kernel sources
From: Junio C Hamano @ 2005-11-08 22:18 UTC (permalink / raw)
To: lamikr; +Cc: git
In-Reply-To: <43711088.6070701@cc.jyu.fi>
lamikr <lamikr@cc.jyu.fi> writes:
Let me understand what trees are involved. I am not sure from
your description.
1. You based your own development on some kernel snapshot.
2. The kernel snapshot you based 1. is "some version".
3. Mvista has d24aff0b commit that contains their changes to
a kernel snapshot (the same "some version" as 2).
4. Mvista now has different version, descendant of 3. This is
the top of omap tree you cloned.
--------------------------->[2] yours
/
[1]------------->[3]----------->[4] omap tip
Is this the commit history graph you have?
> I would now like to revert the sources in git working dir to state that
> was after this d24aff0bd3e788d69a45a9d1b1eecda88d847a41 commit
> and then make the diff between that kernel source version and my non-git
> source version.
You lost me here. Presumably the ultimate goal of what you are
doing is either one of the following:
(1) port your good changes between [1] and [2] on top of [4], or
(2) port progresses in omap tree between [3] and [4] (or perhaps
[1] and [4], including changes betwen [1] and [3]) on top of
your tree [2].
But I am not sure what you mean by the above paragraph. You
sound as if you want to find out the differences between [3]
("revert it to d24aff") and [2] ("your non-git source").
If that is what you want instead, assuming you have your kernel
tree in linux-lamikr and omap tree in linux-omap:
$ cd linux-omap
$ git checkout -b snapshot-d24aff0b d24aff0b
$ cd ..
$ diff -ru -X linux-lamikr/Documentation/dontdiff \
linux-omap linux-lamikr
would give you the diff between [3] and [2]; if the difference
between [1] and [3] is insignificant, then that diff can be
applied to [4]. However, if you have much stuff going on
between [1] and [2], applying "single diff containing
everything" may turn out to be not so useful.
> 2) Does git-diff support making the diff between git's working dir and
> "my non" git kernel source dir.
> Or should I just just use normal diff and order that to ignore .git dir
> and .gitignore files?
Another possibility would be to move your development to .git;
if you know the commit id of [1], then you can branch from that
commit and replay your development trail step by step up to [2].
This obviously requires that you used some SCM to keep track
your development trail between [1] and [2].
Once you have done that (and assuming your branch is called
lamikr), you could compare omap and your tip with:
$ git checkout lamikr
$ git diff lamikr origin
Or even merge omap tip into your branch:
$ git checkout lamikr
$ git pull . origin
all inside linux-omap/ directory.
^ permalink raw reply
* [PATCH] sparse fixes for http-{fetch,push}.c
From: Peter Hagervall @ 2005-11-08 22:18 UTC (permalink / raw)
To: junkio; +Cc: git
Make a bunch of needlessly global functions static, and replace two
K&R-style declarations.
Signed-off-by: Peter Hagervall <hager@cs.umu.se>
---
diff --git a/http-fetch.c b/http-fetch.c
index ea8af1b..88b74b4 100644
--- a/http-fetch.c
+++ b/http-fetch.c
@@ -569,7 +569,7 @@ static void release_request(struct trans
}
#ifdef USE_CURL_MULTI
-void process_curl_messages(void)
+static void process_curl_messages(void)
{
int num_messages;
struct active_request_slot *slot;
@@ -625,7 +625,7 @@ void process_curl_messages(void)
}
}
-void process_request_queue(void)
+static void process_request_queue(void)
{
struct transfer_request *request = request_queue_head;
struct active_request_slot *slot = active_queue_head;
diff --git a/http-push.c b/http-push.c
index 0b90fb9..8866189 100644
--- a/http-push.c
+++ b/http-push.c
@@ -595,7 +595,7 @@ static void start_move(struct transfer_r
}
}
-int refresh_lock(struct active_lock *lock)
+static int refresh_lock(struct active_lock *lock)
{
struct active_request_slot *slot;
char *if_header;
@@ -726,7 +726,7 @@ static void release_request(struct trans
}
#ifdef USE_CURL_MULTI
-void process_curl_messages(void)
+static void process_curl_messages(void)
{
int num_messages;
struct active_request_slot *slot;
@@ -766,7 +766,7 @@ void process_curl_messages(void)
}
}
-void process_request_queue(void)
+static void process_request_queue(void)
{
struct transfer_request *request = request_queue_head;
struct active_request_slot *slot = active_queue_head;
@@ -799,7 +799,7 @@ void process_request_queue(void)
}
#endif
-void process_waiting_requests(void)
+static void process_waiting_requests(void)
{
struct active_request_slot *slot = active_queue_head;
@@ -812,7 +812,7 @@ void process_waiting_requests(void)
}
}
-void add_request(unsigned char *sha1, struct active_lock *lock)
+static void add_request(unsigned char *sha1, struct active_lock *lock)
{
struct transfer_request *request = request_queue_head;
struct packed_git *target;
@@ -939,7 +939,7 @@ static int setup_index(unsigned char *sh
return 0;
}
-static int fetch_indices()
+static int fetch_indices(void)
{
unsigned char sha1[20];
char *url;
@@ -1189,7 +1189,7 @@ end_lockprop_element(void *userData, con
}
}
-struct active_lock *lock_remote(char *file, long timeout)
+static struct active_lock *lock_remote(char *file, long timeout)
{
struct active_request_slot *slot;
struct buffer out_buffer;
@@ -1318,7 +1318,7 @@ struct active_lock *lock_remote(char *fi
return new_lock;
}
-int unlock_remote(struct active_lock *lock)
+static int unlock_remote(struct active_lock *lock)
{
struct active_request_slot *slot;
char *lock_token_header;
@@ -1359,7 +1359,7 @@ int unlock_remote(struct active_lock *lo
return rc;
}
-int check_locking()
+static int check_locking(void)
{
struct active_request_slot *slot;
struct buffer in_buffer;
@@ -1425,7 +1425,7 @@ int check_locking()
return 1;
}
-int is_ancestor(unsigned char *sha1, struct commit *commit)
+static int is_ancestor(unsigned char *sha1, struct commit *commit)
{
struct commit_list *parents;
@@ -1446,8 +1446,8 @@ int is_ancestor(unsigned char *sha1, str
return 0;
}
-void get_delta(unsigned char *sha1, struct object *obj,
- struct active_lock *lock)
+static void get_delta(unsigned char *sha1, struct object *obj,
+ struct active_lock *lock)
{
struct commit *commit;
struct commit_list *parents;
@@ -1503,7 +1503,7 @@ void get_delta(unsigned char *sha1, stru
}
}
-int update_remote(unsigned char *sha1, struct active_lock *lock)
+static int update_remote(unsigned char *sha1, struct active_lock *lock)
{
struct active_request_slot *slot;
char *out_data;
^ permalink raw reply related
* Re: Comments on recursive merge..
From: Linus Torvalds @ 2005-11-08 21:52 UTC (permalink / raw)
To: Fredrik Kuivinen; +Cc: Johannes Schindelin, Junio C Hamano, git
In-Reply-To: <20051108210211.GA23265@c165.ib.student.liu.se>
On Tue, 8 Nov 2005, Fredrik Kuivinen wrote:
>
> * The code for finding common ancestors is also written in Python and
> is probably a bit slower than git-merge-base.
Btw, what part of git-merge-bases is it that makes it not be practical?
Linus
^ permalink raw reply
* Re: Comments on recursive merge..
From: Junio C Hamano @ 2005-11-08 21:47 UTC (permalink / raw)
To: Fredrik Kuivinen; +Cc: Johannes Schindelin, Linus Torvalds, git
In-Reply-To: <20051108210211.GA23265@c165.ib.student.liu.se>
Fredrik Kuivinen <freku045@student.liu.se> writes:
> The second reason is that with the fall back list the recursive
> strategy will only be used in the strange corner cases and will thus
> not get nearly the same amount of testing it would get if it was the
> first choice (or directly after the really-trivial merge).
There are two reasons to avoid git-merge choose from more than
one strategy.
1. The whole idea that git-merge implements "goodness" metric is
bogus. It does not know what merge strategy is good and that
is the reason it punts and has the user choose his preferred
strategy.
2. When it is going to loop over more than one strategy, it
stashes away the current working tree state, so that the
second and subsequent strategies can begin from a clean slate
(including local modifications since the current head). If
we try only one, there is no such cost involved.
I think the patch I sent out last night to change the recursive
as the default strategy and make it overridable from the
configuration mechanism would be a better way to give people
more exposure to the greatness of recursive while protecting
them from potential glitches if any.
^ permalink raw reply
* Re: Expected Behavior?
From: Junio C Hamano @ 2005-11-08 21:41 UTC (permalink / raw)
To: Fredrik Kuivinen; +Cc: Jon Loeliger, git
In-Reply-To: <20051108210332.GB23265@c165.ib.student.liu.se>
Fredrik Kuivinen <freku045@student.liu.se> writes:
> Jon: You could try to this merge with the recursive merge strategy
> (git merge -s recursive 'merge message' master dev) If you do, you
> _should_ get something like:
>
> CONFLICT (add/add): File file3 added non-identically in both
> branches. Adding as file3_master and file3_dev instead.
>
> You will then end up with file3_master and file3_dev in your working
> tree, which corresponds to file3 in the master branch and file3 in the
> dev branch, respectively.
Oops, I missed that part. This is unsafe in theory, if you
could overwrite existing file3_master or file3_dev. Does that
matter in practice?
^ permalink raw reply
* Re: make tests ignorable with "make -i"
From: Alex Riesen @ 2005-11-08 21:16 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vmzkfey4o.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano, Tue, Nov 08, 2005 20:29:59 +0100:
> > ... (Or to ignore plainly uninteresting situations because of the
> > testing being done on say... cygwin ;)
>
> Could you tell us which ones break on Cygwin?
>
of course. I remember t4000-diff-format having problems, using chmod +x
and comparing the results afterwards (it's not really cygwin problem,
but FAT). I let the whole suite running tomorrow and just post the
failed here (instead of dreaming how nice would it be to live in a
perfect world).
^ permalink raw reply
* Re: Expected Behavior?
From: Fredrik Kuivinen @ 2005-11-08 21:03 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jon Loeliger, git
In-Reply-To: <7vwtjjllw4.fsf@assigned-by-dhcp.cox.net>
On Mon, Nov 07, 2005 at 10:00:11PM -0800, Junio C Hamano wrote:
> Jon Loeliger <jdl@freescale.com> writes:
>
> > That is, after the merge, file3 appears to have simply kept
> > the contents of the current, master branch. Why wasn't the
> > dev branch represented here?
> >
> > I _almost_ think I get it, and then *poof*...
>
> Automerge completely punted for this path, and at this point, it
> is still unmerged:
>
> ------------
> $ git ls-files --unmerged
> 100644 c4da0eb.... 2 file3
> 100644 fbc2aa4.... 3 file3
> ------------
>
> Three-way "git-read-tree -m -u O A B" (O is for old, A is ours
> and B is hers) puts O in stage1, A in stage2 and B in stage3.
> This path did not exist in O so we only have them in stage2 and
> stage3. You could compare the stages like this:
>
Jon: You could try to this merge with the recursive merge strategy
(git merge -s recursive 'merge message' master dev) If you do, you
_should_ get something like:
CONFLICT (add/add): File file3 added non-identically in both
branches. Adding as file3_master and file3_dev instead.
You will then end up with file3_master and file3_dev in your working
tree, which corresponds to file3 in the master branch and file3 in the
dev branch, respectively.
- Fredrik
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox