* Re: thin packs ending up fat
From: Junio C Hamano @ 2012-01-13 0:14 UTC (permalink / raw)
To: Jeff King; +Cc: git, Nicolas Pitre
In-Reply-To: <20120112223234.GA4949@sigill.intra.peff.net>
Jeff King <peff@peff.net> writes:
> Hmm. It turns out this is really easy, because we have already marked
> such objects as preferred bases.
>
> So with this patch:
>
> diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
> index 96c1680..d05e228 100644
> --- a/builtin/pack-objects.c
> +++ b/builtin/pack-objects.c
> @@ -1439,6 +1439,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
> */
> if (reuse_delta && trg_entry->in_pack &&
> trg_entry->in_pack == src_entry->in_pack &&
> + !src_entry->preferred_base &&
> trg_entry->in_pack_type != OBJ_REF_DELTA &&
> trg_entry->in_pack_type != OBJ_OFS_DELTA)
> return 0;
Yeah, I was wondering why this one-liner was not in the original message
;-)
> here are the numbers I get:
>
> dataset
> | fetches | tags
> ---------------------------------
> before | 53358 | 2750977
> size after | 32398 | 2668479
> change | -39% | -3%
> ---------------------------------
> before | 0.18 | 1.12
> CPU after | 0.18 | 1.15
> change | +0% | +3%
Looks good.
^ permalink raw reply
* Re: thin packs ending up fat
From: Junio C Hamano @ 2012-01-13 1:31 UTC (permalink / raw)
To: Jeff King; +Cc: git, Nicolas Pitre
In-Reply-To: <20120112223234.GA4949@sigill.intra.peff.net>
From: Jeff King <peff@peff.net>
Subject: [PATCH] thin-pack: try harder to create delta against preferred base
When creating a pack using objects that reside in existing packs, we try
to avoid recomputing futile delta between an object (trg) and a candidate
for its base object (src) if they are stored in the same packfile, and trg
is not recorded as a delta already. This heuristics makes sense because it
is likely that we tried to express trg as a delta based on src but it did
not produce a good delta when we created the existing pack.
As the pack heuristics prefer producing delta to remove data, and Linus's
law dictates that the size of a file grows over time, we tend to record
the newest version of the file as inflated, and older ones as delta
against it.
When creating a thin-pack to transfer recent history, it is likely that we
will try to send an object that is recorded in full, as it is newer. But
the heuristics to avoid recomputing futile delta effectively forbids us
from attempting to express such an object as a delta based on another
object. Sending an object in full is often more expensive than sending a
suboptimal delta based on other objects, and it is even more so if we
could use an object we know the receiving end already has (i.e. referred
base object) as the delta base.
Tweak the recomputation avoidance logic, so that we do not punt on
computing delta against a preferred base object.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
builtin/pack-objects.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index c6e2d87..8bfe3a6 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -1248,11 +1248,16 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
return -1;
/*
- * We do not bother to try a delta that we discarded
- * on an earlier try, but only when reusing delta data.
+ * We do not bother to try a delta that we discarded on an
+ * earlier try, but only when reusing delta data. Note that
+ * src_entry that is marked as the preferred_base should always
+ * be considered, as even if we produce a suboptimal delta against
+ * it, we will still save the transfer cost, as we already know
+ * the other side has it and we won't send src_entry at all.
*/
if (reuse_delta && trg_entry->in_pack &&
trg_entry->in_pack == src_entry->in_pack &&
+ !src_entry->preferred_base &&
trg_entry->in_pack_type != OBJ_REF_DELTA &&
trg_entry->in_pack_type != OBJ_OFS_DELTA)
return 0;
--
1.7.9.rc0.53.gc8bc2
^ permalink raw reply related
* Re: thin packs ending up fat
From: Jeff King @ 2012-01-13 1:51 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Nicolas Pitre
In-Reply-To: <7vwr8wz8u9.fsf@alter.siamese.dyndns.org>
On Thu, Jan 12, 2012 at 05:31:42PM -0800, Junio C Hamano wrote:
> From: Jeff King <peff@peff.net>
> Subject: [PATCH] thin-pack: try harder to create delta against preferred base
I just sat down to write a nicer commit message, and behold, it was done
for me. Thanks.
> When creating a thin-pack to transfer recent history, it is likely that we
> will try to send an object that is recorded in full, as it is newer. But
> the heuristics to avoid recomputing futile delta effectively forbids us
> from attempting to express such an object as a delta based on another
> object. Sending an object in full is often more expensive than sending a
> suboptimal delta based on other objects, and it is even more so if we
> could use an object we know the receiving end already has (i.e. referred
> base object) as the delta base.
s/referred/preferred/
> Tweak the recomputation avoidance logic, so that we do not punt on
> computing delta against a preferred base object.
>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Other than that, it looks good to me.
Signed-off-by: Jeff King <peff@peff.net>
I'll try to deploy this to GitHub in the near future. I doubt we'll see
much of a dent in our bandwidth, though, as small fetches that this
helps are probably lost in the noise of clones.
-Peff
^ permalink raw reply
* Re: thin packs ending up fat
From: Jeff King @ 2012-01-13 1:59 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Nicolas Pitre
In-Reply-To: <20120113015117.GA8245@sigill.intra.peff.net>
On Thu, Jan 12, 2012 at 08:51:17PM -0500, Jeff King wrote:
> > Tweak the recomputation avoidance logic, so that we do not punt on
> > computing delta against a preferred base object.
> >
> > Signed-off-by: Junio C Hamano <gitster@pobox.com>
>
> Other than that, it looks good to me.
>
> Signed-off-by: Jeff King <peff@peff.net>
Actually, Nicolas asked for the numbers to go into the
commit message (and gave his acked-by). So maybe append:
The effect of this patch can be seen on two simulated
upload-pack workloads. The first is based on 44 reflog
entries from my git.git origin/master reflog, and represents
the packs that kernel.org produced to send me git updates
for the past month or two. The second workload represents
much larger fetches, going from git's v1.0.0 tag to v1.1.0,
then v1.1.0 to v1.2.0, and so on.
The table below shows the average generated pack size and
the average CPU time consumed for each dataset, both before
and after the patch:
dataset
| reflog | tags
---------------------------------
before | 53358 | 2750977
size after | 32398 | 2668479
change | -39% | -3%
---------------------------------
before | 0.18 | 1.12
CPU after | 0.18 | 1.15
change | +0% | +3%
This patch makes a much bigger difference for packs with a
shorter slice of history (since its effect is seen at the
boundaries of the pack) though it has some benefit even for
larger packs.
Acked-by: Nicolas Pitre <nico@fluxnic.net>
^ permalink raw reply
* Re: thin packs ending up fat
From: Nicolas Pitre @ 2012-01-13 2:19 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git
In-Reply-To: <7vwr8wz8u9.fsf@alter.siamese.dyndns.org>
On Thu, 12 Jan 2012, Junio C Hamano wrote:
> From: Jeff King <peff@peff.net>
> Subject: [PATCH] thin-pack: try harder to create delta against preferred base
>
> When creating a pack using objects that reside in existing packs, we try
> to avoid recomputing futile delta between an object (trg) and a candidate
> for its base object (src) if they are stored in the same packfile, and trg
> is not recorded as a delta already. This heuristics makes sense because it
> is likely that we tried to express trg as a delta based on src but it did
> not produce a good delta when we created the existing pack.
>
> As the pack heuristics prefer producing delta to remove data, and Linus's
> law dictates that the size of a file grows over time, we tend to record
> the newest version of the file as inflated, and older ones as delta
> against it.
>
> When creating a thin-pack to transfer recent history, it is likely that we
> will try to send an object that is recorded in full, as it is newer. But
> the heuristics to avoid recomputing futile delta effectively forbids us
> from attempting to express such an object as a delta based on another
> object. Sending an object in full is often more expensive than sending a
> suboptimal delta based on other objects, and it is even more so if we
> could use an object we know the receiving end already has (i.e. referred
> base object) as the delta base.
>
> Tweak the recomputation avoidance logic, so that we do not punt on
> computing delta against a preferred base object.
>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Acked-by: Nicolas Pitre <nico@fluxnic.net>
> ---
>
> builtin/pack-objects.c | 9 +++++++--
> 1 files changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
> index c6e2d87..8bfe3a6 100644
> --- a/builtin/pack-objects.c
> +++ b/builtin/pack-objects.c
> @@ -1248,11 +1248,16 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
> return -1;
>
> /*
> - * We do not bother to try a delta that we discarded
> - * on an earlier try, but only when reusing delta data.
> + * We do not bother to try a delta that we discarded on an
> + * earlier try, but only when reusing delta data. Note that
> + * src_entry that is marked as the preferred_base should always
> + * be considered, as even if we produce a suboptimal delta against
> + * it, we will still save the transfer cost, as we already know
> + * the other side has it and we won't send src_entry at all.
> */
> if (reuse_delta && trg_entry->in_pack &&
> trg_entry->in_pack == src_entry->in_pack &&
> + !src_entry->preferred_base &&
> trg_entry->in_pack_type != OBJ_REF_DELTA &&
> trg_entry->in_pack_type != OBJ_OFS_DELTA)
> return 0;
> --
> 1.7.9.rc0.53.gc8bc2
>
^ permalink raw reply
* Re: problem with updating a shallow clone via a branch fetch
From: Rahul Jain @ 2012-01-13 4:09 UTC (permalink / raw)
To: git
In-Reply-To: <AANLkTimSRG+UkD1vJszUf+3j0nV+_pPWSE3N2Dy9SfTa@mail.gmail.com>
I was also getting the same error. I went to .git/shallow file and deleted
<hash>. After that everything was working fine.
^ permalink raw reply
* Re: git svn clone terminating prematurely (I think)
From: Steven Michalske @ 2012-01-13 7:10 UTC (permalink / raw)
To: Steven Line; +Cc: git
In-Reply-To: <CAJ1a7SpRP5GymPrpEchuNk3xwkJLHBKjsXY_85Xs_LAzXtWYuw@mail.gmail.com>
Steven,
In this case nohup seems like a pain. There is a utility called "screen" available on most unixes.
It allows you to create a virtual terminal that you can detach from. After you detach you can log out, some time later log back in and then reattach.
Steve
On Jan 12, 2012, at 10:25 AM, Steven Line wrote:
> Thank you Jonathan.
>
> I had a breakthrough yesterday on this problem. To make a long story
> short my ssh connection to the server where I was running 'nohup git
> svn clone' was timing out. Additionally the nohup I was using wasn't
> really protecting the git svn clone process so an hour or two after
> the ssh disconnected, the git would terminate leaving me with an
> imcomplete repository. I don't understand why the nohup wasn't
> working yet. So my problem wasn't due to git itself.
>
> I started my most recent git svn clone and it's now been running for
> 18 hours. I'm optimistic that I've solved the problem. If my git
> does terminate early then I'll try a 'git svn fetch' to complete the
> clone, based on what you said in your post.
>
> --
> Steven Line
> 303-910-1212
> sline00@gmail.com
> --
> 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
^ permalink raw reply
* Re: thin packs ending up fat
From: Junio C Hamano @ 2012-01-13 7:19 UTC (permalink / raw)
To: Jeff King; +Cc: git, Nicolas Pitre
In-Reply-To: <20120113015117.GA8245@sigill.intra.peff.net>
Jeff King <peff@peff.net> writes:
> On Thu, Jan 12, 2012 at 05:31:42PM -0800, Junio C Hamano wrote:
>
>> From: Jeff King <peff@peff.net>
>> Subject: [PATCH] thin-pack: try harder to create delta against preferred base
>
> I just sat down to write a nicer commit message, and behold, it was done
> for me. Thanks.
Thank _you_ for a quick response and correction.
I wanted to make sure I understood the root cause of the issue and the
approach the patch takes to address it, instead of committing something
that smelled correct. And the only way I know to do so is to write it
down.
Especiallly, before coming up with the description, I was wondering if
this kind of symptom appears in non-thin cases, but after writing down the
justification for this patch, it became clear that we wouldn't have to
worry too much about that case. In a non-thin pack, we need to record one
object at least in a delta family in inflated base form, so we may as well
send that one near the tip that is already in that form for that, letting
the existing "avoid futile delta" heuristics to kick in. Other objects in
the same delta family will delta against it.
^ permalink raw reply
* [PATCH v4 00/10] nd/clone-detached
From: Nguyễn Thái Ngọc Duy @ 2012-01-13 7:21 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1326189427-20800-1-git-send-email-pclouds@gmail.com>
Some comment updates after discussion and squash in the fixup patch.
The code is exactly the same as nd/clone-detached in pu.
Nguyễn Thái Ngọc Duy (10):
t5601: add missing && cascade
clone: write detached HEAD in bare repositories
clone: factor out checkout code
clone: factor out HEAD update code
clone: factor out remote ref writing
clone: delay cloning until after remote HEAD checking
clone: --branch=<branch> always means refs/heads/<branch>
clone: refuse to clone if --branch points to bogus ref
clone: allow --branch to take a tag
clone: print advice on checking out detached HEAD
Documentation/git-clone.txt | 5 +-
advice.c | 14 +++
advice.h | 1 +
builtin/checkout.c | 16 +---
builtin/clone.c | 256 +++++++++++++++++++++++++------------------
t/t5601-clone.sh | 40 ++++++-
t/t5706-clone-branch.sh | 8 +-
transport.c | 5 +-
8 files changed, 211 insertions(+), 134 deletions(-)
--
1.7.3.1.256.g2539c.dirty
^ permalink raw reply
* [PATCH v4 01/10] t5601: add missing && cascade
From: Nguyễn Thái Ngọc Duy @ 2012-01-13 7:21 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1326189427-20800-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
t/t5601-clone.sh | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
index 87ee016..49821eb 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -9,9 +9,9 @@ test_expect_success setup '
rm -fr .git &&
test_create_repo src &&
(
- cd src
- >file
- git add file
+ cd src &&
+ >file &&
+ git add file &&
git commit -m initial
)
--
1.7.3.1.256.g2539c.dirty
^ permalink raw reply related
* [PATCH v4 02/10] clone: write detached HEAD in bare repositories
From: Nguyễn Thái Ngọc Duy @ 2012-01-13 7:21 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1326189427-20800-1-git-send-email-pclouds@gmail.com>
If we don't write, HEAD is still at refs/heads/master as initialized
by init-db, which may or may not match remote's HEAD.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/clone.c | 9 +++------
t/t5601-clone.sh | 25 ++++++++++++++++++++++++-
2 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/builtin/clone.c b/builtin/clone.c
index 86db954..8dde1ea 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -720,12 +720,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
}
} else if (remote_head) {
/* Source had detached HEAD pointing somewhere. */
- if (!option_bare) {
- update_ref(reflog_msg.buf, "HEAD",
- remote_head->old_sha1,
- NULL, REF_NODEREF, DIE_ON_ERR);
- our_head_points_at = remote_head;
- }
+ update_ref(reflog_msg.buf, "HEAD", remote_head->old_sha1,
+ NULL, REF_NODEREF, DIE_ON_ERR);
+ our_head_points_at = remote_head;
} else {
/* Nothing to checkout out */
if (!option_no_checkout)
diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
index 49821eb..e0b8db6 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -12,7 +12,10 @@ test_expect_success setup '
cd src &&
>file &&
git add file &&
- git commit -m initial
+ git commit -m initial &&
+ echo 1 >file &&
+ git add file &&
+ git commit -m updated
)
'
@@ -88,6 +91,26 @@ test_expect_success 'clone --mirror' '
'
+test_expect_success 'clone --mirror with detached HEAD' '
+
+ ( cd src && git checkout HEAD^ && git rev-parse HEAD >../expected ) &&
+ git clone --mirror src mirror.detached &&
+ ( cd src && git checkout - ) &&
+ GIT_DIR=mirror.detached git rev-parse HEAD >actual &&
+ test_cmp expected actual
+
+'
+
+test_expect_success 'clone --bare with detached HEAD' '
+
+ ( cd src && git checkout HEAD^ && git rev-parse HEAD >../expected ) &&
+ git clone --bare src bare.detached &&
+ ( cd src && git checkout - ) &&
+ GIT_DIR=bare.detached git rev-parse HEAD >actual &&
+ test_cmp expected actual
+
+'
+
test_expect_success 'clone --bare names the local repository <name>.git' '
git clone --bare src &&
--
1.7.3.1.256.g2539c.dirty
^ permalink raw reply related
* [PATCH v4 03/10] clone: factor out checkout code
From: Nguyễn Thái Ngọc Duy @ 2012-01-13 7:21 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1326189427-20800-1-git-send-email-pclouds@gmail.com>
Read HEAD from disk instead of relying on local variable
our_head_points_at, so that if earlier code fails to make HEAD
properly, it'll be detected.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/clone.c | 101 +++++++++++++++++++++++++++++++-----------------------
1 files changed, 58 insertions(+), 43 deletions(-)
diff --git a/builtin/clone.c b/builtin/clone.c
index 8dde1ea..100056d 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -448,6 +448,63 @@ static void write_remote_refs(const struct ref *local_refs)
clear_extra_refs();
}
+static int checkout(void)
+{
+ unsigned char sha1[20];
+ char *head;
+ struct lock_file *lock_file;
+ struct unpack_trees_options opts;
+ struct tree *tree;
+ struct tree_desc t;
+ int err = 0, fd;
+
+ if (option_no_checkout)
+ return 0;
+
+ head = resolve_refdup("HEAD", sha1, 1, NULL);
+ if (!head) {
+ warning(_("remote HEAD refers to nonexistent ref, "
+ "unable to checkout.\n"));
+ return 0;
+ }
+ if (strcmp(head, "HEAD")) {
+ if (prefixcmp(head, "refs/heads/"))
+ die(_("HEAD not found below refs/heads!"));
+ }
+ free(head);
+
+ /* We need to be in the new work tree for the checkout */
+ setup_work_tree();
+
+ lock_file = xcalloc(1, sizeof(struct lock_file));
+ fd = hold_locked_index(lock_file, 1);
+
+ memset(&opts, 0, sizeof opts);
+ opts.update = 1;
+ opts.merge = 1;
+ opts.fn = oneway_merge;
+ opts.verbose_update = (option_verbosity > 0);
+ opts.src_index = &the_index;
+ opts.dst_index = &the_index;
+
+ tree = parse_tree_indirect(sha1);
+ parse_tree(tree);
+ init_tree_desc(&t, tree->buffer, tree->size);
+ unpack_trees(1, &t, &opts);
+
+ if (write_cache(fd, active_cache, active_nr) ||
+ commit_locked_index(lock_file))
+ die(_("unable to write new index file"));
+
+ err |= run_hook(NULL, "post-checkout", sha1_to_hex(null_sha1),
+ sha1_to_hex(sha1), "1", NULL);
+
+ if (!err && option_recursive)
+ err = run_command_v_opt(argv_submodule, RUN_GIT_CMD);
+
+ return err;
+}
+
static int write_one_config(const char *key, const char *value, void *data)
{
return git_config_set_multivar(key, value ? value : "true", "^$", 0);
@@ -722,13 +779,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
/* Source had detached HEAD pointing somewhere. */
update_ref(reflog_msg.buf, "HEAD", remote_head->old_sha1,
NULL, REF_NODEREF, DIE_ON_ERR);
- our_head_points_at = remote_head;
- } else {
- /* Nothing to checkout out */
- if (!option_no_checkout)
- warning(_("remote HEAD refers to nonexistent ref, "
- "unable to checkout.\n"));
- option_no_checkout = 1;
}
if (transport) {
@@ -736,42 +786,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
transport_disconnect(transport);
}
- if (!option_no_checkout) {
- struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
- struct unpack_trees_options opts;
- struct tree *tree;
- struct tree_desc t;
- int fd;
-
- /* We need to be in the new work tree for the checkout */
- setup_work_tree();
-
- fd = hold_locked_index(lock_file, 1);
-
- memset(&opts, 0, sizeof opts);
- opts.update = 1;
- opts.merge = 1;
- opts.fn = oneway_merge;
- opts.verbose_update = (option_verbosity > 0);
- opts.src_index = &the_index;
- opts.dst_index = &the_index;
-
- tree = parse_tree_indirect(our_head_points_at->old_sha1);
- parse_tree(tree);
- init_tree_desc(&t, tree->buffer, tree->size);
- unpack_trees(1, &t, &opts);
-
- if (write_cache(fd, active_cache, active_nr) ||
- commit_locked_index(lock_file))
- die(_("unable to write new index file"));
-
- err |= run_hook(NULL, "post-checkout", sha1_to_hex(null_sha1),
- sha1_to_hex(our_head_points_at->old_sha1), "1",
- NULL);
-
- if (!err && option_recursive)
- err = run_command_v_opt(argv_submodule, RUN_GIT_CMD);
- }
+ err = checkout();
strbuf_release(&reflog_msg);
strbuf_release(&branch_top);
--
1.7.3.1.256.g2539c.dirty
^ permalink raw reply related
* [PATCH v4 04/10] clone: factor out HEAD update code
From: Nguyễn Thái Ngọc Duy @ 2012-01-13 7:21 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1326189427-20800-1-git-send-email-pclouds@gmail.com>
While at it, update the comment at "if (remote_head)"
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/clone.c | 41 ++++++++++++++++++++++++-----------------
1 files changed, 24 insertions(+), 17 deletions(-)
diff --git a/builtin/clone.c b/builtin/clone.c
index 100056d..baed5ae 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -448,6 +448,29 @@ static void write_remote_refs(const struct ref *local_refs)
clear_extra_refs();
}
+static void update_head(const struct ref *our, const struct ref *remote,
+ const char *msg)
+{
+ if (our) {
+ /* Local default branch link */
+ create_symref("HEAD", our->name, NULL);
+ if (!option_bare) {
+ const char *head = skip_prefix(our->name, "refs/heads/");
+ update_ref(msg, "HEAD", our->old_sha1, NULL, 0, DIE_ON_ERR);
+ install_branch_config(0, head, option_origin, our->name);
+ }
+ } else if (remote) {
+ /*
+ * We know remote HEAD points to a non-branch, or
+ * HEAD points to a branch but we don't know which one, or
+ * we asked for a specific branch but it did not exist.
+ * Detach HEAD in all these cases.
+ */
+ update_ref(msg, "HEAD", remote->old_sha1,
+ NULL, REF_NODEREF, DIE_ON_ERR);
+ }
+}
+
static int checkout(void)
{
unsigned char sha1[20];
@@ -763,23 +786,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
reflog_msg.buf);
}
- if (our_head_points_at) {
- /* Local default branch link */
- create_symref("HEAD", our_head_points_at->name, NULL);
- if (!option_bare) {
- const char *head = skip_prefix(our_head_points_at->name,
- "refs/heads/");
- update_ref(reflog_msg.buf, "HEAD",
- our_head_points_at->old_sha1,
- NULL, 0, DIE_ON_ERR);
- install_branch_config(0, head, option_origin,
- our_head_points_at->name);
- }
- } else if (remote_head) {
- /* Source had detached HEAD pointing somewhere. */
- update_ref(reflog_msg.buf, "HEAD", remote_head->old_sha1,
- NULL, REF_NODEREF, DIE_ON_ERR);
- }
+ update_head(our_head_points_at, remote_head, reflog_msg.buf);
if (transport) {
transport_unlock_pack(transport);
--
1.7.3.1.256.g2539c.dirty
^ permalink raw reply related
* [PATCH v4 05/10] clone: factor out remote ref writing
From: Nguyễn Thái Ngọc Duy @ 2012-01-13 7:21 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1326189427-20800-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/clone.c | 36 ++++++++++++++++++++++++------------
1 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/builtin/clone.c b/builtin/clone.c
index baed5ae..d1d6dca 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -448,6 +448,28 @@ static void write_remote_refs(const struct ref *local_refs)
clear_extra_refs();
}
+static void update_remote_refs(const struct ref *refs,
+ const struct ref *mapped_refs,
+ const struct ref *remote_head_points_at,
+ const char *branch_top,
+ const char *msg)
+{
+ if (refs) {
+ clear_extra_refs();
+ write_remote_refs(mapped_refs);
+ }
+
+ if (remote_head_points_at && !option_bare) {
+ struct strbuf head_ref = STRBUF_INIT;
+ strbuf_addstr(&head_ref, branch_top);
+ strbuf_addstr(&head_ref, "HEAD");
+ create_symref(head_ref.buf,
+ remote_head_points_at->peer_ref->name,
+ msg);
+ }
+
+}
+
static void update_head(const struct ref *our, const struct ref *remote,
const char *msg)
{
@@ -740,10 +762,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
}
if (refs) {
- clear_extra_refs();
-
- write_remote_refs(mapped_refs);
-
remote_head = find_ref_by_name(refs, "HEAD");
remote_head_points_at =
guess_remote_head(remote_head, mapped_refs, 0);
@@ -777,14 +795,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
"refs/heads/master");
}
- if (remote_head_points_at && !option_bare) {
- struct strbuf head_ref = STRBUF_INIT;
- strbuf_addstr(&head_ref, branch_top.buf);
- strbuf_addstr(&head_ref, "HEAD");
- create_symref(head_ref.buf,
- remote_head_points_at->peer_ref->name,
- reflog_msg.buf);
- }
+ update_remote_refs(refs, mapped_refs, remote_head_points_at,
+ branch_top.buf, reflog_msg.buf);
update_head(our_head_points_at, remote_head, reflog_msg.buf);
--
1.7.3.1.256.g2539c.dirty
^ permalink raw reply related
* [PATCH v4 06/10] clone: delay cloning until after remote HEAD checking
From: Nguyễn Thái Ngọc Duy @ 2012-01-13 7:21 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1326189427-20800-1-git-send-email-pclouds@gmail.com>
This gives us an opportunity to abort the command during remote HEAD
check without wasting much bandwidth.
Cloning with remote-helper remains before the check because the remote
helper updates mapped_refs, which is necessary for remote ref checks.
foreign_vcs field is used to indicate the transport is handled by
remote helper.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/clone.c | 54 +++++++++++++++++++++++++++---------------------------
transport.c | 5 ++++-
2 files changed, 31 insertions(+), 28 deletions(-)
diff --git a/builtin/clone.c b/builtin/clone.c
index d1d6dca..a9d06a4 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -361,13 +361,8 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
closedir(dir);
}
-static const struct ref *clone_local(const char *src_repo,
- const char *dest_repo)
+static void clone_local(const char *src_repo, const char *dest_repo)
{
- const struct ref *ret;
- struct remote *remote;
- struct transport *transport;
-
if (option_shared) {
struct strbuf alt = STRBUF_INIT;
strbuf_addf(&alt, "%s/objects", src_repo);
@@ -383,13 +378,8 @@ static const struct ref *clone_local(const char *src_repo,
strbuf_release(&dest);
}
- remote = remote_get(src_repo);
- transport = transport_get(remote, src_repo);
- ret = transport_get_remote_refs(transport);
- transport_disconnect(transport);
if (0 <= option_verbosity)
printf(_("done.\n"));
- return ret;
}
static const char *junk_work_tree;
@@ -581,6 +571,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT;
struct transport *transport = NULL;
char *src_ref_prefix = "refs/heads/";
+ struct remote *remote;
int err = 0;
struct refspec *refspec;
@@ -732,13 +723,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
strbuf_reset(&value);
- if (is_local) {
- refs = clone_local(path, git_dir);
- mapped_refs = wanted_peer_refs(refs, refspec);
- } else {
- struct remote *remote = remote_get(option_origin);
- transport = transport_get(remote, remote->url[0]);
+ remote = remote_get(option_origin);
+ transport = transport_get(remote, remote->url[0]);
+ if (!is_local) {
if (!transport->get_refs_list || !transport->fetch)
die(_("Don't know how to clone %s"), transport->url);
@@ -753,14 +741,23 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
if (option_upload_pack)
transport_set_option(transport, TRANS_OPT_UPLOADPACK,
option_upload_pack);
-
- refs = transport_get_remote_refs(transport);
- if (refs) {
- mapped_refs = wanted_peer_refs(refs, refspec);
- transport_fetch_refs(transport, mapped_refs);
- }
}
+ refs = transport_get_remote_refs(transport);
+ mapped_refs = refs ? wanted_peer_refs(refs, refspec) : NULL;
+
+ /*
+ * mapped_refs may be updated if transport-helper is used so
+ * we need fetch it early because remote_head code below
+ * relies on it.
+ *
+ * for normal clones, transport_get_remote_refs() should
+ * return reliable ref set, we can delay cloning until after
+ * remote HEAD check.
+ */
+ if (!is_local && remote->foreign_vcs && refs)
+ transport_fetch_refs(transport, mapped_refs);
+
if (refs) {
remote_head = find_ref_by_name(refs, "HEAD");
remote_head_points_at =
@@ -795,15 +792,18 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
"refs/heads/master");
}
+ if (is_local)
+ clone_local(path, git_dir);
+ else if (refs && !remote->foreign_vcs)
+ transport_fetch_refs(transport, mapped_refs);
+
update_remote_refs(refs, mapped_refs, remote_head_points_at,
branch_top.buf, reflog_msg.buf);
update_head(our_head_points_at, remote_head, reflog_msg.buf);
- if (transport) {
- transport_unlock_pack(transport);
- transport_disconnect(transport);
- }
+ transport_unlock_pack(transport);
+ transport_disconnect(transport);
err = checkout();
diff --git a/transport.c b/transport.c
index a99b7c9..4366639 100644
--- a/transport.c
+++ b/transport.c
@@ -895,8 +895,10 @@ struct transport *transport_get(struct remote *remote, const char *url)
while (is_urlschemechar(p == url, *p))
p++;
- if (!prefixcmp(p, "::"))
+ if (!prefixcmp(p, "::")) {
helper = xstrndup(url, p - url);
+ remote->foreign_vcs = helper;
+ }
}
if (helper) {
@@ -938,6 +940,7 @@ struct transport *transport_get(struct remote *remote, const char *url)
char *handler = xmalloc(len + 1);
handler[len] = 0;
strncpy(handler, url, len);
+ remote->foreign_vcs = handler;
transport_helper_init(ret, handler);
}
--
1.7.3.1.256.g2539c.dirty
^ permalink raw reply related
* [PATCH v4 07/10] clone: --branch=<branch> always means refs/heads/<branch>
From: Nguyễn Thái Ngọc Duy @ 2012-01-13 7:21 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1326189427-20800-1-git-send-email-pclouds@gmail.com>
It does not make sense to look outside refs/heads for HEAD's target
(src_ref_prefix can be set to "refs/" if --mirror is used) because ref
code only allows symref in form refs/heads/...
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/clone.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/builtin/clone.c b/builtin/clone.c
index a9d06a4..89ba6f0 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -463,7 +463,7 @@ static void update_remote_refs(const struct ref *refs,
static void update_head(const struct ref *our, const struct ref *remote,
const char *msg)
{
- if (our) {
+ if (our && !prefixcmp(our->name, "refs/heads/")) {
/* Local default branch link */
create_symref("HEAD", our->name, NULL);
if (!option_bare) {
@@ -765,7 +765,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
if (option_branch) {
struct strbuf head = STRBUF_INIT;
- strbuf_addstr(&head, src_ref_prefix);
+ strbuf_addstr(&head, "refs/heads/");
strbuf_addstr(&head, option_branch);
our_head_points_at =
find_ref_by_name(mapped_refs, head.buf);
--
1.7.3.1.256.g2539c.dirty
^ permalink raw reply related
* [PATCH v4 08/10] clone: refuse to clone if --branch points to bogus ref
From: Nguyễn Thái Ngọc Duy @ 2012-01-13 7:22 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1326189427-20800-1-git-send-email-pclouds@gmail.com>
It's possible that users make a typo in the branch name. Stop and let
users recheck. Falling back to remote's HEAD is not documented any
way.
Except when using remote helper, the pack has not been transferred at
this stage yet so we don't waste much bandwidth.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/clone.c | 13 +++++--------
t/t5706-clone-branch.sh | 8 ++------
2 files changed, 7 insertions(+), 14 deletions(-)
diff --git a/builtin/clone.c b/builtin/clone.c
index 89ba6f0..6a2886a 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -474,8 +474,7 @@ static void update_head(const struct ref *our, const struct ref *remote,
} else if (remote) {
/*
* We know remote HEAD points to a non-branch, or
- * HEAD points to a branch but we don't know which one, or
- * we asked for a specific branch but it did not exist.
+ * HEAD points to a branch but we don't know which one.
* Detach HEAD in all these cases.
*/
update_ref(msg, "HEAD", remote->old_sha1,
@@ -771,12 +770,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
find_ref_by_name(mapped_refs, head.buf);
strbuf_release(&head);
- if (!our_head_points_at) {
- warning(_("Remote branch %s not found in "
- "upstream %s, using HEAD instead"),
- option_branch, option_origin);
- our_head_points_at = remote_head_points_at;
- }
+ if (!our_head_points_at)
+ die(_("Remote branch %s not found in "
+ "upstream %s, using HEAD instead"),
+ option_branch, option_origin);
}
else
our_head_points_at = remote_head_points_at;
diff --git a/t/t5706-clone-branch.sh b/t/t5706-clone-branch.sh
index f3f9a76..56be67e 100755
--- a/t/t5706-clone-branch.sh
+++ b/t/t5706-clone-branch.sh
@@ -57,12 +57,8 @@ test_expect_success 'clone -b does not munge remotes/origin/HEAD' '
)
'
-test_expect_success 'clone -b with bogus branch chooses HEAD' '
- git clone -b bogus parent clone-bogus &&
- (cd clone-bogus &&
- check_HEAD master &&
- check_file one
- )
+test_expect_success 'clone -b with bogus branch' '
+ test_must_fail git clone -b bogus parent clone-bogus
'
test_done
--
1.7.3.1.256.g2539c.dirty
^ permalink raw reply related
* [PATCH v4 09/10] clone: allow --branch to take a tag
From: Nguyễn Thái Ngọc Duy @ 2012-01-13 7:22 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1326189427-20800-1-git-send-email-pclouds@gmail.com>
Because a tag ref cannot be put to HEAD, HEAD will become detached.
This is consistent with "git checkout <tag>".
This is mostly useful in shallow clone, where it allows you to clone a
tag in addtion to branches.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-clone.txt | 5 +++--
builtin/clone.c | 13 +++++++++++++
t/t5601-clone.sh | 9 +++++++++
3 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 4b8b26b..db2b29c 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -146,8 +146,9 @@ objects from the source repository into a pack in the cloned repository.
-b <name>::
Instead of pointing the newly created HEAD to the branch pointed
to by the cloned repository's HEAD, point to `<name>` branch
- instead. In a non-bare repository, this is the branch that will
- be checked out.
+ instead. `--branch` can also take tags and treat them like
+ detached HEAD. In a non-bare repository, this is the branch
+ that will be checked out.
--upload-pack <upload-pack>::
-u <upload-pack>::
diff --git a/builtin/clone.c b/builtin/clone.c
index 6a2886a..a3c8f78 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -471,6 +471,11 @@ static void update_head(const struct ref *our, const struct ref *remote,
update_ref(msg, "HEAD", our->old_sha1, NULL, 0, DIE_ON_ERR);
install_branch_config(0, head, option_origin, our->name);
}
+ } else if (our) {
+ struct commit *c = lookup_commit_reference(our->old_sha1);
+ /* --branch specifies a non-branch (i.e. tags), detach HEAD */
+ update_ref(msg, "HEAD", c->object.sha1,
+ NULL, REF_NODEREF, DIE_ON_ERR);
} else if (remote) {
/*
* We know remote HEAD points to a non-branch, or
@@ -770,6 +775,14 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
find_ref_by_name(mapped_refs, head.buf);
strbuf_release(&head);
+ if (!our_head_points_at) {
+ strbuf_addstr(&head, "refs/tags/");
+ strbuf_addstr(&head, option_branch);
+ our_head_points_at =
+ find_ref_by_name(mapped_refs, head.buf);
+ strbuf_release(&head);
+ }
+
if (!our_head_points_at)
die(_("Remote branch %s not found in "
"upstream %s, using HEAD instead"),
diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
index e0b8db6..67869b4 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -271,4 +271,13 @@ test_expect_success 'clone from original with relative alternate' '
grep /src/\\.git/objects target-10/objects/info/alternates
'
+test_expect_success 'clone checking out a tag' '
+ git clone --branch=some-tag src dst.tag &&
+ GIT_DIR=src/.git git rev-parse some-tag >expected &&
+ test_cmp expected dst.tag/.git/HEAD &&
+ GIT_DIR=dst.tag/.git git config remote.origin.fetch >fetch.actual &&
+ echo "+refs/heads/*:refs/remotes/origin/*" >fetch.expected &&
+ test_cmp fetch.expected fetch.actual
+'
+
test_done
--
1.7.3.1.256.g2539c.dirty
^ permalink raw reply related
* [PATCH v4 10/10] clone: print advice on checking out detached HEAD
From: Nguyễn Thái Ngọc Duy @ 2012-01-13 7:22 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1326189427-20800-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
advice.c | 14 ++++++++++++++
advice.h | 1 +
builtin/checkout.c | 16 +---------------
builtin/clone.c | 5 ++++-
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/advice.c b/advice.c
index e02e632..3e1a145 100644
--- a/advice.c
+++ b/advice.c
@@ -64,3 +64,17 @@ void NORETURN die_resolve_conflict(const char *me)
error_resolve_conflict(me);
die("Exiting because of an unresolved conflict.");
}
+
+void detach_advice(const char *new_name)
+{
+ const char fmt[] =
+ "Note: checking out '%s'.\n\n"
+ "You are in 'detached HEAD' state. You can look around, make experimental\n"
+ "changes and commit them, and you can discard any commits you make in this\n"
+ "state without impacting any branches by performing another checkout.\n\n"
+ "If you want to create a new branch to retain commits you create, you may\n"
+ "do so (now or later) by using -b with the checkout command again. Example:\n\n"
+ " git checkout -b new_branch_name\n\n";
+
+ fprintf(stderr, fmt, new_name);
+}
diff --git a/advice.h b/advice.h
index e5d0af7..7bda45b 100644
--- a/advice.h
+++ b/advice.h
@@ -14,5 +14,6 @@ int git_default_advice_config(const char *var, const char *value);
void advise(const char *advice, ...);
int error_resolve_conflict(const char *me);
extern void NORETURN die_resolve_conflict(const char *me);
+void detach_advice(const char *new_name);
#endif /* ADVICE_H */
diff --git a/builtin/checkout.c b/builtin/checkout.c
index f1984d9..5bf96ba 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -514,20 +514,6 @@ static void report_tracking(struct branch_info *new)
strbuf_release(&sb);
}
-static void detach_advice(const char *old_path, const char *new_name)
-{
- const char fmt[] =
- "Note: checking out '%s'.\n\n"
- "You are in 'detached HEAD' state. You can look around, make experimental\n"
- "changes and commit them, and you can discard any commits you make in this\n"
- "state without impacting any branches by performing another checkout.\n\n"
- "If you want to create a new branch to retain commits you create, you may\n"
- "do so (now or later) by using -b with the checkout command again. Example:\n\n"
- " git checkout -b new_branch_name\n\n";
-
- fprintf(stderr, fmt, new_name);
-}
-
static void update_refs_for_switch(struct checkout_opts *opts,
struct branch_info *old,
struct branch_info *new)
@@ -575,7 +561,7 @@ static void update_refs_for_switch(struct checkout_opts *opts,
REF_NODEREF, DIE_ON_ERR);
if (!opts->quiet) {
if (old->path && advice_detached_head)
- detach_advice(old->path, new->name);
+ detach_advice(new->name);
describe_detached_head(_("HEAD is now at"), new->commit);
}
} else if (new->path) { /* Switch branches. */
diff --git a/builtin/clone.c b/builtin/clone.c
index a3c8f78..bfdafaa 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -506,7 +506,10 @@ static int checkout(void)
"unable to checkout.\n"));
return 0;
}
- if (strcmp(head, "HEAD")) {
+ if (!strcmp(head, "HEAD")) {
+ if (advice_detached_head)
+ detach_advice(sha1_to_hex(sha1));
+ } else {
if (prefixcmp(head, "refs/heads/"))
die(_("HEAD not found below refs/heads!"));
}
--
1.7.3.1.256.g2539c.dirty
^ permalink raw reply related
* Re: thin packs ending up fat
From: Ævar Arnfjörð Bjarmason @ 2012-01-13 8:28 UTC (permalink / raw)
To: Jeff King; +Cc: git, Nicolas Pitre
In-Reply-To: <20120112221523.GA3663@sigill.intra.peff.net>
On Thu, Jan 12, 2012 at 23:15, Jeff King <peff@peff.net> wrote:
I'd be interested in testing this on some other repos I have. How
exactly did you get this:
> -- >8 --
> 8b0e15fa95e11965f18c8d2585dc8ffd9bfc9356 ^7f41b6bbe3181dc4d1687db036bf22316997a1bf
> 34c4461ae3b353e8c931565d5527b98ed12e3735 ^8b0e15fa95e11965f18c8d2585dc8ffd9bfc9356
> 463b0ea22b5b9a882e8140d0308433d8cbd0d1fe ^34c4461ae3b353e8c931565d5527b98ed12e3735
> 288396994f077eec7e7db0017838a5afbfbf81e3 ^463b0ea22b5b9a882e8140d0308433d8cbd0d1fe
> 05f6edcd2a418a88eeb953d51408a6aeef312f5c ^288396994f077eec7e7db0017838a5afbfbf81e3
> 08cfdbb88cd6225b4fc4b8a3cecd0e01758c835d ^05f6edcd2a418a88eeb953d51408a6aeef312f5c
>From this:
> In the first, I used the reflog entries from my
> refs/remotes/origin/master ref.
I can't make "git reflog refs/remotes/..." show me anything similar.
^ permalink raw reply
* fetch for bare repository
From: Dmitry A. Ashkadov @ 2012-01-13 10:42 UTC (permalink / raw)
To: git
Hello!
I can't understand how to fetch branches from external repository for
bare repository.
For example, imagine 2 git repositories: "B" and "C". "B" repository is
external repository and it contains branch "branch1". "C" is an internal
repository (special repository for some people). "C" repository may be
created with command:
> $ git clone --bare B .
For "C" repository working set isn't required, so it may be bare, I
think. This new "C" repository contains branch "branch1".
Imagine that somebody has created a new branch "branch2" in the
repository "B". I don't know what I should do with repository "C" to
make the branch "branch2" available on repository "C". Command:
> $ git fetch origin
doesn't work. Next command for repository "C":
> $ git branch -a
always shows only branch "branch1" but never branch "branch2".
Could you help me, please?
Thank you!
^ permalink raw reply
* Re: Bug? Git checkout fails with a wrong error message
From: Holger Hellmuth @ 2012-01-13 12:50 UTC (permalink / raw)
To: Yves Goergen; +Cc: git
In-Reply-To: <loom.20120112T193624-86@post.gmane.org>
On 12.01.2012 19:44, Yves Goergen wrote:
> Hi,
Important information missing: What version of git are you using? Should
the version number begin with 1.6 or even lower you will get the advice
to update your version to something non-ancient. Lots of bug-fixes
happened in-between.
> I am using Git alone for my local software project in Visual Studio 2010. I've
> been on the master branch most of the time. Recently I created a new branch to
> do a larger refactoring of one of the dialogue windows. I did the following
> modifications:
>
> * Rename Form1 to Form1a (including all depending files)
> * Add new Form1
>
> I checked this change into the branch, say form-refactoring. Interestingly, Git
> didn't notice that I renamed the file Form1.cs into Form1a.cs and created a
> brand new, totally different Form1.cs, but instead it noticed a new Form1a.cs
I assume .cs is a C source file for visual studio, not a generated file,
right ?
> file and found a whole lot of differences between the previous and new Form1.cs
> files. This will of course lead to totally garbaged diffs, but I don't care in
> this case as long as all files are handled correctly in the end.
git does not record renames like cvs/svn do. It operates on snapshots
and infers renames through comparisions. So if the next commit has a
file missing and the same or similar file contents under some different
path, it reports it as a rename. You can try -M with git log or git diff
so that git expends more effort to detect renames+edits. Or you could
avoid doing renames and edits of the same file in the same commit.
But apart from the cosmetic inconvenience of a non-sensical diff this
commit wasn't more difficult or special as any other commit. git doesn't
care if a commit changes one line or a thousand. So I don't this
renaming in itself did somehow confuse git.
> Then I switched back to master to do some other small changes. Nothing
> conflicting. Until now, everything worked fine.
>
> Today, I wanted to switch back to my branch form-refactoring to continue that
> work. But all I get is the following message:
>
> -----
> git.exe checkout form-refactoring
>
> Aborting
> error: The following untracked working tree files would be overwritten by
> checkout:
> Form1.Designer.cs
> Please move or remove them before you can switch branches.
> -----
You didn't mention that filename before (please assume people not
accustomed to the ways of Visual Studio 2010). Is that another file you
renamed and created new in the form-refactoring branch?
What does git diff -- Form1.Designer.cs' say?
What does 'git diff form-refactoring -- Form1.Designer.cs' say?
> What is that supposed to be? The mentioned file is not untracked. Neither in the
> master branch, nor in the form-refactoring branch. It is part of both branches,
> but one is not a descendent of the other (because it was recreated on the
> form-refactoring branch, if that matters). What would happen if I delete it, is
> it gone for good then? I don't trust Git to bring back the correct file if I
You can copy the file to somewhere outside of git and do 'git checkout
-- Form1.Designer.cs'. A comparision of the two files should show you
that git still has the files recorded.
> Right now, I cannot continue with my work because I cannot switch branches. Is
> there an easy solution to this? Is my Git repository broken, all by standard
> operations?
The easy solution is: Make a backup of the repository, then 'git
checkout -f form-refactoring'. My uneducated guess is that the problem
has to do with an old git version and white space or filenames with
different case on a case-insensitive file system or some other problem
that leads to a misinterpretation. But as I said, uneducated guess!
^ permalink raw reply
* Re: fetch for bare repository
From: Carlos Martín Nieto @ 2012-01-13 13:40 UTC (permalink / raw)
To: Dmitry A. Ashkadov; +Cc: git
In-Reply-To: <4F100A7B.3030001@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 941 bytes --]
On Fri, Jan 13, 2012 at 02:42:03PM +0400, Dmitry A. Ashkadov wrote:
> Hello!
>
> I can't understand how to fetch branches from external repository
> for bare repository.
What you probably want is a mirror (git clone --mirror). Unless you
tell git that you want a mirror, it's going to assume that you want a
bare repo to push your own changes up to it. Such a repo has no need
to be kept up to date, so clone doesn't set up any fetch refspecs.
Stepping back, do you need to fetch those branches into the private
repo? If you still have access to the main repo and that's where the
main project development is happening, why not use upstream's repo to
get those changes to your local repo (as in the one you use to work)?
It sounds like you're trying to replicate a centralised VCS'
workflow. Git works like a network and you can merge a branch from
upstream if you need to and then push to the private repo.
cmn
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 490 bytes --]
^ permalink raw reply
* Re: fetch for bare repository
From: Dmitry A. Ashkadov @ 2012-01-13 13:54 UTC (permalink / raw)
To: Carlos Martín Nieto, git
In-Reply-To: <20120113134058.GB2850@centaur.lab.cmartin.tk>
13.01.2012 17:40, Carlos Martín Nieto пишет:
> On Fri, Jan 13, 2012 at 02:42:03PM +0400, Dmitry A. Ashkadov wrote:
>> Hello!
>>
>> I can't understand how to fetch branches from external repository
>> for bare repository.
> What you probably want is a mirror (git clone --mirror). Unless you
> tell git that you want a mirror, it's going to assume that you want a
> bare repo to push your own changes up to it. Such a repo has no need
> to be kept up to date, so clone doesn't set up any fetch refspecs.
I don't have access to an origin repository. So, I need bare repository
and push changes up to it. So, I think the word "mirror" isn't
applicable to private repository.
> Stepping back, do you need to fetch those branches into the private
> repo? If you still have access to the main repo and that's where the
> main project development is happening, why not use upstream's repo to
> get those changes to your local repo (as in the one you use to work)?
> It sounds like you're trying to replicate a centralised VCS'
> workflow. Git works like a network and you can merge a branch from
> upstream if you need to and then push to the private repo.
Yes, I can add one more remote to my local repository, then fetch
changes from it and push it to private repository. But I thought that
update private repository is the best way.
Thank you!
^ permalink raw reply
* Re: [PATCH 1/2] gitweb: Fix file links in "grep" search
From: Thomas Perl @ 2012-01-13 14:09 UTC (permalink / raw)
To: Jakub Narebski; +Cc: Junio C Hamano, git
In-Reply-To: <201201052126.49087.jnareb@gmail.com>
Hi,
2012/1/5 Jakub Narebski <jnareb@gmail.com>:
> There were two bugs in generating file links (links to "blob" view),
> one hidden by the other. The correct way of generating file link is
>
> href(action=>"blob", hash_base=>$co{'id'},
> file_name=>$file);
>
> It was $co{'hash'} (this key does not exist, and therefore this is
> undef), and 'hash' instead of 'hash_base'.
> [...]
> Thomas, could you check if this fixes your issue?
Sorry for taking a bit longer to respond on this one, but I just got
around to test all problematic cases that I described with the patch
applied - it fixes the problem for me (i.e. I can successfully grep in
non-master branches and then clicking the link brings me to the right
location).
As far as I'm concerned, the patch can be applied and fixes the bug.
Thanks for the quick fix! :)
Thomas
^ 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