Git development
 help / color / mirror / Atom feed
* Re: move files between disparate repos and maintain version history
From: Jeff King @ 2009-03-03  4:13 UTC (permalink / raw)
  To: davetron5000; +Cc: git
In-Reply-To: <0d8965bb-e2ed-4f49-b323-c110f605ae2c@33g2000yqm.googlegroups.com>

On Mon, Mar 02, 2009 at 12:30:58PM -0800, davetron5000 wrote:

> So, is there a way I can move a file between two git repositories,
> maintaining the change history?  I guess it would be something like
> "apply all patches that this file was involved in, but ONLY apply the
> ones affecting this file, to the new repo, then delete from the old"?

Yes, that's more or less how you would do it. There are actually two
separate issues, and each has two possible solutions.

Issue 1 is moving the history to the new repo.

One solution is, as you guessed, to export as patches and import into
the new repo:

  cd /path/to/app
  git format-patch --stdout --root -- <path> >~/patches
  cd /path/to/core
  git am ~/patches

where <path> can be a file, directory, or a list of either or both.
This should work fine if the history of that path is linear, since a
list of patches is, by definition, linear. You can see the "shape" of
the history with:

  cd /path/to/app
  gitk -- <path>

The other solution is to actually rewrite a version of git history that
sees only those paths, then merge it in. That will retain the actual
shape of the history. You can do this using "git filter-branch":

  cd /path/to/app
  # we do our work on a temporary branch
  git branch just-path
  # the actual filter; note you could do more than just grep here
  # if you wanted to munge the pathnames
  git filter-branch --index-filter '
    git ls-files -s | grep path |
      GIT_INDEX_FILE="$GIT_INDEX_FILE.new" git update-index --index-info &&
    mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"
  ' --prune-empty just-path

  # you can inspect just-path at this point with "gitk just-path"
  cd /path/to/core
  # and then pull it into core's history
  git pull /path/to/app just-path

The second issue is what you want to have happen in the "app"
repository. Presumably you no longer want the moved files there. You
_could_ filter-branch to pretend as if they were always in "core" and
never in "app". But that is probably not a good idea because:

  1. You are rewriting history, which will make merging more complex for
     your users.

  2. You may be breaking historical builds which expect the files to be
     there in the past.

So I think you're probably best to just remove them with a new commit
and have the duplicated history in both.

-Peff

PS I think you might be able to replace the filter-branch invocation
with a fast-export / fast-import pipeline, but I haven't tried.

^ permalink raw reply

* Re: How can I merge some files rather than all files modified on one  branch to my branch?
From: Emily Ren @ 2009-03-03  3:56 UTC (permalink / raw)
  To: Boyd Stephen Smith Jr.; +Cc: git
In-Reply-To: <200903022110.23207.bss@iguanasuicide.net>

Junio and Boyd,

Thank you very much for your kindly guide ! I'll try these method.

Boyd,
How to rewrite the history of the branch ?

Thanks,
Emily

On Tue, Mar 3, 2009 at 11:10 AM, Boyd Stephen Smith Jr.
<bss@iguanasuicide.net> wrote:
> On Monday 02 March 2009 03:19:05 Emily Ren wrote:
>> I want to merge some files rather than all files modified on one
>> branch to my branch, how can I do?
>
> In addition to what Junio suggested, I'll offer another method, assuming the
> branch you are merging from is not yet published:
> (1) Rewrite the history of the to-be-merged branch so that all the changes to
> the files you want occur "before" and in separate commits from the file you
> want to ignore.  So the current tree:
>
> A-->B-->C (yours)
>  \
>  ->D-->E (theirs)
>
> becomes:
>
> A-->B-->C (yours)
>  \
>  ->D1-->E1-->D2-->E2 (theirs)
>
> with D1 and D2 being the separate parts of commit D and similarly for E1 and
> E2.
>
> (2) Merge in the rewritten history, but only the part that you want, giving:
>
> A-->B-->C--->F (yours)
>  \         /
>  ->D1-->E1-->D2-->E2 (theirs)
>
> This preserves the full intent of what you are trying to do, a partial merge.
> If you merge "theirs" in fully at some point in the future, you shouldn't see
> any conflicts arising from not recording the merge or missing changes arising
> from recording a full merge that did not happen.
> --
> Boyd Stephen Smith Jr.                   ,= ,-_-. =.
> bss@iguanasuicide.net                   ((_/)o o(\_))
> ICQ: 514984 YM/AIM: DaTwinkDaddy         `-'(. .)`-'
> http://iguanasuicide.net/                    \_/
>
>

^ permalink raw reply

* Re: How can I merge some files rather than all files modified on one branch to my branch?
From: Boyd Stephen Smith Jr. @ 2009-03-03  3:10 UTC (permalink / raw)
  To: Emily Ren; +Cc: git
In-Reply-To: <856bfe0e0903020119y68188a39m90c683949220b2f@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1351 bytes --]

On Monday 02 March 2009 03:19:05 Emily Ren wrote:
> I want to merge some files rather than all files modified on one
> branch to my branch, how can I do?

In addition to what Junio suggested, I'll offer another method, assuming the 
branch you are merging from is not yet published:
(1) Rewrite the history of the to-be-merged branch so that all the changes to 
the files you want occur "before" and in separate commits from the file you 
want to ignore.  So the current tree:

A-->B-->C (yours)
 \
  ->D-->E (theirs)

becomes:

A-->B-->C (yours)
 \
  ->D1-->E1-->D2-->E2 (theirs)

with D1 and D2 being the separate parts of commit D and similarly for E1 and 
E2.

(2) Merge in the rewritten history, but only the part that you want, giving:

A-->B-->C--->F (yours)
 \         /
  ->D1-->E1-->D2-->E2 (theirs)

This preserves the full intent of what you are trying to do, a partial merge.  
If you merge "theirs" in fully at some point in the future, you shouldn't see 
any conflicts arising from not recording the merge or missing changes arising 
from recording a full merge that did not happen.
-- 
Boyd Stephen Smith Jr.                   ,= ,-_-. =.
bss@iguanasuicide.net                   ((_/)o o(\_))
ICQ: 514984 YM/AIM: DaTwinkDaddy         `-'(. .)`-'
http://iguanasuicide.net/                    \_/


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* Re: [PATCH v2] send-email: add --confirm option
From: Junio C Hamano @ 2009-03-03  2:47 UTC (permalink / raw)
  To: Jay Soffian; +Cc: git, Nanako Shiraishi, Paul Gortmaker
In-Reply-To: <1235924234-16923-1-git-send-email-jaysoffian@gmail.com>

Jay Soffian <jaysoffian@gmail.com> writes:

>  - When the user specifies "all" in response to a confirm prompt, we
>    hint them about how to use "sendemail.confirm" config setting.

I think the logic is wrong.  Even when you have configured to usually ask,
you may want to say "I know Cc settings for this particular series is all
good, but I still want the safety in my future invocations.".

How about doing it this way instead?

> @@ -346,6 +350,13 @@ if ($suppress_cc{'body'}) {
>  	delete $suppress_cc{'body'};
>  }
>  
> +# Set confirm
> +if (!defined $confirm) {
> +	$confirm = scalar %suppress_cc ? 'compose' : 'auto';

This is not "Set confirm" but "set the default value to $confirm".  Also
set $confirm_unconfigured = "true" here.

> @@ -837,6 +836,27 @@ X-Mailer: git-send-email $gitversion
>  	unshift (@sendmail_parameters,
>  			'-f', $raw_from) if(defined $envelope_sender);
> +	if ($needs_confirm && !$dry_run) {

And use it here; give some help for people who haven't seen this new
message and haven't decided:

	    if (!$confirm_unconfigured) {
		print "By default the command asks if you are sure about\n";
		print "the CC list computed from various places.  If you\n";
                print "do not want this confirmation step, you can say\n";
                print "    $ git config --global sendemail.confirm never\n";
                print "to squelch it.\n";
		print "A good setting might be:\n";
                print "    $ git config --global sendemail.confirm auto\n";
		print "to squelch this help text that is given until you\n";
		print "configure the variable to some value.\n";
	    }

> +		print "\n$header\n";
> +		while (1) {
> +			chomp ($_ = $term->readline(
> +				"Send this email? ([y]es|[n]o|[q]uit|[a]ll): "
> +			));
> +			last if /^(?:yes|y|no|n|quit|q|all|a)/i;
> +			print "\n";
> +		}
> +		if (/^n/i) {
> +			return;
> +		} elsif (/^q/i) {
> +			cleanup_compose_files();
> +			exit(0);
> +		} elsif (/^a/i) {
> +			$confirm = 'never';

And drop the following two:

> +			print "You may disable all future prompting via sendemail.confirm;\n";
> +			print "Run 'git send-email --help' for details.\n";
> +		}
> +	}

^ permalink raw reply

* Re: [PATCH] git filter-branch: Process commits in --date-order
From: Peter Rosin @ 2009-03-03  0:39 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git
In-Reply-To: <alpine.DEB.1.00.0903030126530.10279@pacific.mpi-cbg.de>

Hi Johannes,

Den 2009-03-03 01:28 skrev Johannes Schindelin:
> Hi,
> 
> On Tue, 3 Mar 2009, Peter Rosin wrote:
> 
>> When converting an svn repository to git, I am filtering the commits
>> using --msg-filter. During this conversion I want to use the
>> .git-rewrite/map data to fill in references to other commits. In the
>> svn repo, there is a commit message e.g. "Cherry-pick r207", and I
>> want to append "r207 = <commit>" to the git commit message, as r207
>> no longer means very much. This works fine when the git commit
>> corresponding to r207 has been filtered before the current commit, and
>> is present in the map. When filtering in --topo-order, this is not
>> always the case, making it impossible to look up the git commit.
> 
> I'd rather have this as an option.  God knows what breaks with time-skewed 
> repositories if you use date-order instead of topo-order, and I'd rather 
> not break that not quite uncommon case.

Well, from the git rev-list docs:

        --date-order
               This option is similar to --topo-order in the sense that no
               parent comes before all of its children, but otherwise things
               are still ordered in the commit timestamp order.

Sounds pretty safe to me?

Cheers,
Peter

^ permalink raw reply

* Re: [PATCH] rebase -i: avoid 'git reset' when possible
From: Junio C Hamano @ 2009-03-03  0:57 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Sverre Rabbelier, Stephen Haberman, Shawn O. Pearce, Thomas Rast,
	Git Mailing List, Stephan Beyer, Christian Couder,
	Daniel Barkalow
In-Reply-To: <alpine.DEB.1.00.0903012242180.10279@pacific.mpi-cbg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> Or even
>
> 	current=$ONTO
> 	fd=3
> 	while read command sha1 rest
> 	do
> 		case "$fd,$command,$current" in
> 		3,pick,"$sha1"*|t,p,"$sha1"*)
> 			current=$sha1
> 			;;
> 		*)
> 			fd=1
> 			;;
> 		esac
> 		echo "$command $sha1 $rest" >&$fd
> 	done < "$TODO" > "$TODO.new" 3>> "$DONE" &&
> 	mv "$TODO.new" "$TODO"
>
> Hmm?

Certainly.

Even though "3 means we haven't found a non-pick yet" feels slightly
hacky, the logic is contained in this small loop and I do not see it as a
problem.  As long as you are sure $ONTO and all sha1 can be compared
without running them through rev-parse, avoiding rev-parse per iteration
is a very attractive optimization.

^ permalink raw reply

* Re: [PATCH] git filter-branch: Process commits in --date-order
From: Junio C Hamano @ 2009-03-03  0:51 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Peter Rosin, git
In-Reply-To: <alpine.DEB.1.00.0903030126530.10279@pacific.mpi-cbg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> On Tue, 3 Mar 2009, Peter Rosin wrote:
>
>> When converting an svn repository to git, I am filtering the commits
>> using --msg-filter. During this conversion I want to use the
>> .git-rewrite/map data to fill in references to other commits. In the
>> svn repo, there is a commit message e.g. "Cherry-pick r207", and I
>> want to append "r207 = <commit>" to the git commit message, as r207
>> no longer means very much. This works fine when the git commit
>> corresponding to r207 has been filtered before the current commit, and
>> is present in the map. When filtering in --topo-order, this is not
>> always the case, making it impossible to look up the git commit.
>
> I'd rather have this as an option.  God knows what breaks with time-skewed 
> repositories if you use date-order instead of topo-order, and I'd rather 
> not break that not quite uncommon case.

I am wondering if it even makes sense to allow users to disable
topological ordering.

Doesn't filter-branch have the same "child commits build on top of parent
commits" dependency as fast-export has?  And didn't you guys fix
fast-export recently?

^ permalink raw reply

* Re: remote branches, and branch names in general
From: Jakub Narebski @ 2009-03-03  0:38 UTC (permalink / raw)
  To: John Dlugosz; +Cc: git
In-Reply-To: <450196A1AAAE4B42A00A8B27A59278E709F07398@EXCHANGE.trad.tradestation.com>

"John Dlugosz" <JDlugosz@TradeStation.com> writes:

> I see the remote branches with names of the form remotes/pub/name where
> pub is the nickname of the place I pull from.  To specify such branches,
> must I always spell it out with the leading "remotes/", or can that be
> shorted or implied somehow?  

You usually can omit "remotes/" prefix, and just use
"<remote>/<branch>" (or even "<remote>" for "<remote>/HEAD"). You need
it only if there is need for disambiguation.

> 
> Meanwhile, I see that branch names can be hierarchical, as I found out
> when I accidently created a branch called "pub/xxx".  So I'm wondering
> about the usefulness of using that for organizing topic branches based
> on assigned tasks organization and the person owning that branch.

Junio uses branches like 'fc/parseopt-config' (initials + feature)
in git development...

-- 
Jakub Narebski
Poland
ShadeHawk on #git

^ permalink raw reply

* [PATCH v2] git-clone: Add option --branch to override initial branch
From: Tor Arne Vestbø @ 2009-03-03  0:33 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Johannes.Schindelin
In-Reply-To: <alpine.DEB.1.00.0903030047130.10279@pacific.mpi-cbg.de>

The options --branch and -b allow the user to override the initial
branch created and checked out by git-clone (normally this is the
active branch of the remote repository).

If the selected branch is not found the operation aborts.

Signed-off-by: Tor Arne Vestbø <torarnv@gmail.com>
---

Something like this?

Documentation/git-clone.txt |    5 +++++
 builtin-clone.c             |   32 ++++++++++++++++++++++++++++----
 2 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 95f08b9..e7feb4d 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -119,6 +119,11 @@ then the cloned repository will become corrupt.
 	Instead of using the remote name 'origin' to keep track
 	of the upstream repository, use <name> instead.
 
+--branch <name>::
+-b <name>::
+	Instead of using the remote repository's active branch as the
+	initial branch, use <name> instead.
+
 --upload-pack <upload-pack>::
 -u <upload-pack>::
 	When given, and the repository to clone from is accessed
diff --git a/builtin-clone.c b/builtin-clone.c
index c338910..5fc01ce 100644
--- a/builtin-clone.c
+++ b/builtin-clone.c
@@ -38,6 +38,7 @@ static int option_quiet, option_no_checkout, option_bare, option_mirror;
 static int option_local, option_no_hardlinks, option_shared;
 static char *option_template, *option_reference, *option_depth;
 static char *option_origin = NULL;
+static char *option_branch = NULL;
 static char *option_upload_pack = "git-upload-pack";
 static int option_verbose;
 
@@ -66,6 +67,8 @@ static struct option builtin_clone_options[] = {
 		   "path to git-upload-pack on the remote"),
 	OPT_STRING(0, "depth", &option_depth, "depth",
 		    "create a shallow clone of that depth"),
+	OPT_STRING('b', "branch", &option_branch, "branch",
+		    "initial remote branch to check out"),
 
 	OPT_END()
 };
@@ -372,7 +375,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	const char *repo_name, *repo, *work_tree, *git_dir;
 	char *path, *dir;
 	int dest_exists;
-	const struct ref *refs, *head_points_at, *remote_head, *mapped_refs;
+	const struct ref *refs, *mapped_refs;
+	const struct ref *remote_head = NULL;
+	const struct ref *head_points_at = NULL;
 	struct strbuf key = STRBUF_INIT, value = STRBUF_INIT;
 	struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT;
 	struct transport *transport = NULL;
@@ -545,12 +550,31 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 
 		mapped_refs = write_remote_refs(refs, &refspec, reflog_msg.buf);
 
-		head_points_at = locate_head(refs, mapped_refs, &remote_head);
+		if (option_branch) {
+		    const int offset = 11;
+		    const char *branch = option_branch;
+		    if (!prefixcmp(branch, "refs/heads/"))
+			branch += offset;
+
+		    const struct ref *r;
+		    for (r = mapped_refs; r; r = r->next) {
+			if (!strcmp(r->name + offset, branch)) {
+			    /* Override initial branch */
+			    head_points_at = r;
+			    remote_head = r;
+			    break;
+			}
+		    }
+
+		    if (!head_points_at)
+			die("remote has no branch named '%s'.", option_branch);
+
+		} else {
+		    head_points_at = locate_head(refs, mapped_refs, &remote_head);
+		}
 	}
 	else {
 		warning("You appear to have cloned an empty repository.");
-		head_points_at = NULL;
-		remote_head = NULL;
 		option_no_checkout = 1;
 		if (!option_bare)
 			install_branch_config("master", option_origin,
-- 
1.6.2.rc2.17.g2aa38

^ permalink raw reply related

* Re: [PATCH] git filter-branch: Process commits in --date-order
From: Johannes Schindelin @ 2009-03-03  0:28 UTC (permalink / raw)
  To: Peter Rosin; +Cc: git
In-Reply-To: <1236035454-12236-1-git-send-email-peda@lysator.liu.se>

Hi,

On Tue, 3 Mar 2009, Peter Rosin wrote:

> When converting an svn repository to git, I am filtering the commits
> using --msg-filter. During this conversion I want to use the
> .git-rewrite/map data to fill in references to other commits. In the
> svn repo, there is a commit message e.g. "Cherry-pick r207", and I
> want to append "r207 = <commit>" to the git commit message, as r207
> no longer means very much. This works fine when the git commit
> corresponding to r207 has been filtered before the current commit, and
> is present in the map. When filtering in --topo-order, this is not
> always the case, making it impossible to look up the git commit.

I'd rather have this as an option.  God knows what breaks with time-skewed 
repositories if you use date-order instead of topo-order, and I'd rather 
not break that not quite uncommon case.

Ciao,
Dscho

^ permalink raw reply

* [PATCH] git filter-branch: Process commits in --date-order
From: Peter Rosin @ 2009-03-02 23:10 UTC (permalink / raw)
  To: git; +Cc: Peter Rosin

When converting an svn repository to git, I am filtering the commits
using --msg-filter. During this conversion I want to use the
.git-rewrite/map data to fill in references to other commits. In the
svn repo, there is a commit message e.g. "Cherry-pick r207", and I
want to append "r207 = <commit>" to the git commit message, as r207
no longer means very much. This works fine when the git commit
corresponding to r207 has been filtered before the current commit, and
is present in the map. When filtering in --topo-order, this is not
always the case, making it impossible to look up the git commit.

Signed-off-by: Peter Rosin <peda@lysator.liu.se>
---
 git-filter-branch.sh |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/git-filter-branch.sh b/git-filter-branch.sh
index 9a09ba1..dbb2bb3 100755
--- a/git-filter-branch.sh
+++ b/git-filter-branch.sh
@@ -257,11 +257,11 @@ mkdir ../map || die "Could not create map/ directory"
 
 case "$filter_subdir" in
 "")
-	git rev-list --reverse --topo-order --default HEAD \
+	git rev-list --reverse --date-order --default HEAD \
 		--parents --simplify-merges "$@"
 	;;
 *)
-	git rev-list --reverse --topo-order --default HEAD \
+	git rev-list --reverse --date-order --default HEAD \
 		--parents --simplify-merges "$@" -- "$filter_subdir"
 esac > ../revs || die "Could not get the commits"
 commits=$(wc -l <../revs | tr -d " ")
-- 
1.6.0.4

^ permalink raw reply related

* Re: [PATCH] git-clone: Add option --branch to override initial branch
From: Tor Arne Vestbø @ 2009-03-03  0:11 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Junio C Hamano, git
In-Reply-To: <alpine.DEB.1.00.0903030047130.10279@pacific.mpi-cbg.de>

Johannes Schindelin wrote:
> On Mon, 2 Mar 2009, Tor Arne Vestbø wrote:
>> The options --branch and -b allow the user to override the initial 
>> branch created and checked out by git-clone. Normally this is the active 
>> branch of the remote repository, which is also the fallback if the 
>> selected branch is not found.
> 
> I do not think that falling back if the selected branch is not found is a 
> wise choice.

Ah, was not sure what the proper response would be. I'll resubmit with a
die() instead.

> Besides, the common way to check out something different than the remote's 
> HEAD is like this:
> 
> 	$ git clone -n $URL
> 	$ cd $DIR
> 	$ git checkout -t origin/$BRANCH

Yepp, plus removing the original branch:

 $ git branch -D $ORIGINAL_ACTIVE_BRANCH # typically master

> I am undecided if that is good enough, or your patch is needed.

The idea was to be able to tell someone "hey, if you want to hack on
some feature for next, do the following:"

 $ git clone git://git.kernel.org/pub/scm/git/git.git -b next

Maybe next is not such a good example, since it does not diverge that
much from master and pu, but imagine a repository with a master, plus
other branches that over time diverge from master (where you would
typically use git-new-workdir to have them in a separate working tree).

In that situation it would be nice to be able to tell someone, hey, if
you want to work on this odd branch which is not master, just do -b.

Tor Arne

^ permalink raw reply

* Re: [PATCH] git-clone: Add option --branch to override initial branch
From: Junio C Hamano @ 2009-03-03  0:09 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Tor Arne Vestbø, git
In-Reply-To: <alpine.DEB.1.00.0903030047130.10279@pacific.mpi-cbg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> Hi,
>
> On Mon, 2 Mar 2009, Tor Arne Vestbø wrote:
>
>> The options --branch and -b allow the user to override the initial 
>> branch created and checked out by git-clone. Normally this is the active 
>> branch of the remote repository, which is also the fallback if the 
>> selected branch is not found.
>
> I do not think that falling back if the selected branch is not found is a 
> wise choice.
>
> Besides, the common way to check out something different than the remote's 
> HEAD is like this:
>
> 	$ git clone -n $URL
> 	$ cd $DIR
> 	$ git checkout -t origin/$BRANCH
>
> I am undecided if that is good enough, or your patch is needed.

I am fairly negative on this one, if it matters.

^ permalink raw reply

* Re: [PATCH] git-clone: Add option --branch to override initial branch
From: Johannes Schindelin @ 2009-03-02 23:48 UTC (permalink / raw)
  To: Tor Arne Vestbø; +Cc: Junio C Hamano, git
In-Reply-To: <1236031882-2052-1-git-send-email-torarnv@gmail.com>

[-- Attachment #1: Type: TEXT/PLAIN, Size: 628 bytes --]

Hi,

On Mon, 2 Mar 2009, Tor Arne Vestbø wrote:

> The options --branch and -b allow the user to override the initial 
> branch created and checked out by git-clone. Normally this is the active 
> branch of the remote repository, which is also the fallback if the 
> selected branch is not found.

I do not think that falling back if the selected branch is not found is a 
wise choice.

Besides, the common way to check out something different than the remote's 
HEAD is like this:

	$ git clone -n $URL
	$ cd $DIR
	$ git checkout -t origin/$BRANCH

I am undecided if that is good enough, or your patch is needed.

Ciao,
Dscho

^ permalink raw reply

* Re: [RFC] Refspec patterns with * in the middle
From: Junio C Hamano @ 2009-03-02 23:30 UTC (permalink / raw)
  To: Daniel Barkalow; +Cc: Jay Soffian, git
In-Reply-To: <alpine.LNX.1.00.0903021746140.19665@iabervon.org>

Daniel Barkalow <barkalow@iabervon.org> writes:

> The issue, in my case, is importing from a system where branches contain 
> projects instead of projects containing branches (and everything is a 
> single namespace). So I want to match an insane (for us) LHS with a sane 
> RHS to get stuff into reasonable shape. I don't really care about any 
> patterns where the branch identifier is multiple components, but I 
> wouldn't be surprised if somebody did.

Isn't this just getting more and more insane?  Is this really worth
supporting, I have to wonder...

> Oh, and it looks like "?" is reserved and currently unused, so we could 
> have * match one or more full path components, and ? match partial path 
> components.

Well, "?" is not allowed exactly because it often is used to match a
single character by things like for-each-ref.

^ permalink raw reply

* [PATCH 2/2] optimize compat/ memmem()
From: René Scharfe @ 2009-03-02 23:19 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <49AC6527.5010808@lsrfire.ath.cx>

When memmem() was imported from glibc 2.2 into compat/, an optimization
was dropped in the process, in order to make the code smaller and simpler.
It was OK because memmem() wasn't used in performance-critical code.  Now
the situation has changed and we can benefit from this optimization.

The trick is to avoid calling memcmp() if the first character of the needle
already doesn't match.  Checking one character directly is much cheaper
than the function call overhead.  We keep the first character of the needle
in the variable named point and the rest in the one named tail.

The following commands were run in a Linux kernel repository and timed, the
best of five results is shown:

  $ STRING='Ensure that the real time constraints are schedulable.'
  $ git log -S"$STRING" HEAD -- kernel/sched.c >/dev/null

On Windows Vista x64, before:

  real    0m8.470s
  user    0m0.000s
  sys     0m0.000s

And after the patch:

  real    0m1.887s
  user    0m0.000s
  sys     0m0.000s

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
This performance fix is a good idea, even if we later decide to import
the latest version of memmem() from Gnulib, I think.  And I'm not so
sure any more that we want to do that in the first place.  More
measurements are needed (which goes for these two patches, too, of
course), but this version should provide a better baseline.

 compat/memmem.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/compat/memmem.c b/compat/memmem.c
index cd0d877..56bcb42 100644
--- a/compat/memmem.c
+++ b/compat/memmem.c
@@ -5,6 +5,8 @@ void *gitmemmem(const void *haystack, size_t haystack_len,
 {
 	const char *begin = haystack;
 	const char *last_possible = begin + haystack_len - needle_len;
+	const char *tail = needle;
+	char point;
 
 	/*
 	 * The first occurrence of the empty string is deemed to occur at
@@ -20,8 +22,9 @@ void *gitmemmem(const void *haystack, size_t haystack_len,
 	if (haystack_len < needle_len)
 		return NULL;
 
+	point = *tail++;
 	for (; begin <= last_possible; begin++) {
-		if (!memcmp(begin, needle, needle_len))
+		if (*begin == point && !memcmp(begin + 1, tail, needle_len - 1))
 			return (void *)begin;
 	}
 
-- 
1.6.2.rc2

^ permalink raw reply related

* proper way to merge?
From: John Dlugosz @ 2009-03-02 23:08 UTC (permalink / raw)
  To: git

Thanks for the input, JohnFlux and Bryan.

Here's what I found worked.

First of all, the overall concept that changes to the repository are
never destructive (as long as you remember where you were) is
liberating.  It's beyond the confidence of an "undo" feature.  Really,
nothing I do can change any of the existing objects and their
interrelationship.  Using the reflog and lightweight tags, and the
feature that gitk still knows the nodes even after the labels move,
makes it easy to experiment on.

Basically, I cherry-picked the commits from "rel" to "dev" and fixed
them as I went.  Leaving it at that, I'd forever see duplicate commits
with the same comments but different actual commits, so things like "git
log here..there" will recognize the equality.

So, to make it look like I actually used the merge command, I did this:

1) I reset back to the original dev before my patching.  The default
reset, mixed, left the working tree unchanged and didn't do anything to
the index either.

2) git merge rel -s ours
That created a new node with the topology I wanted, but didn't actually
do anything.

3) add all the changed files, and "amend" the commit.


I suppose --no-commit would do the same thing as amending, but this way
I saw (in getk) that it really did what I wanted, instead of trusting
the multiple parentage to just be waiting somehow.

If keeping things in the working directory to carry between the steps
gives you the willies, remember that you can always reset --hard back to
where you were before doing (1).  Either because you tagged it just in
case, can find it using HEAD@{something}, or still see it on the screen
in gitk.

But, another approach would be to do the (fake) merge first, and then
keep amending it with the individual changes you pick from the other
branch.  I don't like that because the tree will show something that's
not true, until you are all done.  I want everything to be correct and
not lying if I get interrupted and leave it that way for a while.

Comments welcome.  I'm trying to get my act together before I start
evangelizing to the rest of the team.

--John
(excuse the footer; it's not my choice)

TradeStation Group, Inc. is a publicly-traded holding company (NASDAQ GS: TRAD) of three operating subsidiaries, TradeStation Securities, Inc. (Member NYSE, FINRA, SIPC and NFA), TradeStation Technologies, Inc., a trading software and subscription company, and TradeStation Europe Limited, a United Kingdom, FSA-authorized introducing brokerage firm. None of these companies provides trading or investment advice, recommendations or endorsements of any kind. The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited.
  If you received this in error, please contact the sender and delete the material from any computer.

^ permalink raw reply

* [PATCH 1/2] diffcore-pickaxe: use memmem()
From: René Scharfe @ 2009-03-02 23:00 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <cover.1235629933.git.gitster@pobox.com>

Use memmem() instead of open-coding it.  The system libraries usually have a
much faster version than the memcmp()-loop here.  Even our own fall-back in
compat/, which is used on Windows, is slightly faster.

The following commands were run in a Linux kernel repository and timed, the
best of five results is shown:

  $ STRING='Ensure that the real time constraints are schedulable.'
  $ git log -S"$STRING" HEAD -- kernel/sched.c >/dev/null

On Ubuntu 8.10 x64, before (v1.6.2-rc2):

  8.09user 0.04system 0:08.14elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
  0inputs+0outputs (0major+30952minor)pagefaults 0swaps

And with the patch:

  1.50user 0.04system 0:01.54elapsed 100%CPU (0avgtext+0avgdata 0maxresident)k
  0inputs+0outputs (0major+30645minor)pagefaults 0swaps

On Fedora 10 x64, before:

  8.34user 0.05system 0:08.39elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
  0inputs+0outputs (0major+29268minor)pagefaults 0swaps

And with the patch:

  1.15user 0.05system 0:01.20elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
  0inputs+0outputs (0major+32253minor)pagefaults 0swaps

On Windows Vista x64, before:

  real    0m9.204s
  user    0m0.000s
  sys     0m0.000s

And with the patch:

  real    0m8.470s
  user    0m0.000s
  sys     0m0.000s

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
 diffcore-pickaxe.c |   18 ++++++++----------
 1 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c
index af9fffe..574b3e8 100644
--- a/diffcore-pickaxe.c
+++ b/diffcore-pickaxe.c
@@ -10,7 +10,7 @@ static unsigned int contains(struct diff_filespec *one,
 			     regex_t *regexp)
 {
 	unsigned int cnt;
-	unsigned long offset, sz;
+	unsigned long sz;
 	const char *data;
 	if (diff_populate_filespec(one, 0))
 		return 0;
@@ -33,15 +33,13 @@ static unsigned int contains(struct diff_filespec *one,
 		}
 
 	} else { /* Classic exact string match */
-		/* Yes, I've heard of strstr(), but the thing is *data may
-		 * not be NUL terminated.  Sue me.
-		 */
-		for (offset = 0; offset + len <= sz; offset++) {
-			/* we count non-overlapping occurrences of needle */
-			if (!memcmp(needle, data + offset, len)) {
-				offset += len - 1;
-				cnt++;
-			}
+		while (sz) {
+			const char *found = memmem(data, sz, needle, len);
+			if (!found)
+				break;
+			sz -= found - data + len;
+			data = found + len;
+			cnt++;
 		}
 	}
 	diff_free_filespec_data(one);
-- 
1.6.2.rc2

^ permalink raw reply related

* Re: [RFC] Refspec patterns with * in the middle
From: Daniel Barkalow @ 2009-03-02 23:00 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jay Soffian, git
In-Reply-To: <7v1vtfmtwj.fsf@gitster.siamese.dyndns.org>

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1959 bytes --]

On Mon, 2 Mar 2009, Junio C Hamano wrote:

> Jay Soffian <jaysoffian@gmail.com> writes:
> 
> > On Mon, Mar 2, 2009 at 1:25 PM, Daniel Barkalow <barkalow@iabervon.org> wrote:
> >>> But the following is not:
> >>>
> >>>  - foo/bar*/baz
> >>>
> >>> IOW, '*' can only appear as a non-terminating symbol if it is bounded
> >>> by '/' on each side.
> >>
> >> You have my criterion right, but I want that to be valid, but only match
> >> things like "foo/bar-something/baz", not "foo/bar-a/b/baz".
> >
> > Ah, that makes sense. Perhaps use "**" to mean matching across path
> > components which is what rsync does:
> >
> >  o  a '*' matches any non-empty path component (it stops at slashes).
> >  o  use '**' to match anything, including slashes.
> >
> > ?
> 
> I personally do not think that makes much sense (and I find ** ugly, too).
> 
> We traditionally supported '*' only at the end, and it always has meant
> "match through the end, including slashes".
> 
> Requiring 'match including slashes' to be spelled as '**' only when it is
> not at the end is unnecessarily confusing.
> 
> Is there a valid use case when * wants to match across directory
> boundaries when it is not at the end?  I offhand do not think of a sane
> one.

Maybe:

/refs/imported/$GROUP/$USER/project -> $GROUP/$USER

or

/refs/imported/sandbox/$USER/$TOPIC/project -> $USER/$TOPIC

The issue, in my case, is importing from a system where branches contain 
projects instead of projects containing branches (and everything is a 
single namespace). So I want to match an insane (for us) LHS with a sane 
RHS to get stuff into reasonable shape. I don't really care about any 
patterns where the branch identifier is multiple components, but I 
wouldn't be surprised if somebody did.

Oh, and it looks like "?" is reserved and currently unused, so we could 
have * match one or more full path components, and ? match partial path 
components.

	-Daniel
*This .sig left intentionally blank*

^ permalink raw reply

* Re: [RFC] Refspec patterns with * in the middle
From: Jay Soffian @ 2009-03-02 22:58 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Daniel Barkalow, git
In-Reply-To: <7v1vtfmtwj.fsf@gitster.siamese.dyndns.org>

On Mon, Mar 2, 2009 at 5:39 PM, Junio C Hamano <gitster@pobox.com> wrote:
> I personally do not think that makes much sense (and I find ** ugly, too).
>
> We traditionally supported '*' only at the end, and it always has meant
> "match through the end, including slashes".

Oh, good point, I had not thought that through very well.

> Requiring 'match including slashes' to be spelled as '**' only when it is
> not at the end is unnecessarily confusing.
>
> Is there a valid use case when * wants to match across directory
> boundaries when it is not at the end?  I offhand do not think of a sane
> one.
>
> So, it might make it easiest to understand if we say * usually does not
> match slash, except when it is used at the end immediately after a slash,
> in which case it means "match through the end".

That seems simple enough.

j.

^ permalink raw reply

* RE: proper way to merge?
From: John Dlugosz @ 2009-03-02 22:44 UTC (permalink / raw)
  To: Bryan Donlan; +Cc: git
In-Reply-To: <3e8340490903020033l78329c82la186cadaa528bc32@mail.gmail.com>

===Re:===
So, if I understand correctly, you've manually applied (manually
applying diffs or something?) your changes from the release branch to
the dev branch, and now want to inform git of what happened?

If so, you could commit what you have now, use a graft to change its
parentage, then git-filter-branch to actually update the commit
object. Something like this, I believe:
git commit -m 'Merge .....'
echo '<full 40-character commit ID of the merge> <parent on the dev
branch> <parent on the release branch>' >> .git/info/grafts
git-filter-branch dev~..dev
## You can remove (that line from) .git/info/grafts now

In the future, you may want to perform this sort of incremental merge
by simply git merging intermediate revisions in the release branch.
===end===

That's very interesting.  I did not find 'grafts' in the documentation,
but I looked for it now that I know about it.  So you can add another
parent to the graph just by adding a line to that file.  BTW,
filter-branch isn't available on msysgit.  But leaving it in that grafts
file should be OK -- is that pushed/pulled with everything else?

--John


TradeStation Group, Inc. is a publicly-traded holding company (NASDAQ GS: TRAD) of three operating subsidiaries, TradeStation Securities, Inc. (Member NYSE, FINRA, SIPC and NFA), TradeStation Technologies, Inc., a trading software and subscription company, and TradeStation Europe Limited, a United Kingdom, FSA-authorized introducing brokerage firm. None of these companies provides trading or investment advice, recommendations or endorsements of any kind. The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited.
  If you received this in error, please contact the sender and delete the material from any computer.

^ permalink raw reply

* post-checkout hook not run on clone
From: layer @ 2009-03-02 22:43 UTC (permalink / raw)
  To: git

I realize this might be a feature, but when I switch to the master
branch with "git checkout master" it is, and I would think that a
clone that gets the master branch would also does a sort of "checkout
master" and would run the hook.

In any case, I'd be happy of there was a post-clone hook, instead, but
there isn't.

Any suggestions?

Thanks.

Kevin

^ permalink raw reply

* Re: [RFC] Refspec patterns with * in the middle
From: Junio C Hamano @ 2009-03-02 22:39 UTC (permalink / raw)
  To: Jay Soffian; +Cc: Daniel Barkalow, git
In-Reply-To: <76718490903021407u215fb769g656a8fdc20e622e5@mail.gmail.com>

Jay Soffian <jaysoffian@gmail.com> writes:

> On Mon, Mar 2, 2009 at 1:25 PM, Daniel Barkalow <barkalow@iabervon.org> wrote:
>>> But the following is not:
>>>
>>>  - foo/bar*/baz
>>>
>>> IOW, '*' can only appear as a non-terminating symbol if it is bounded
>>> by '/' on each side.
>>
>> You have my criterion right, but I want that to be valid, but only match
>> things like "foo/bar-something/baz", not "foo/bar-a/b/baz".
>
> Ah, that makes sense. Perhaps use "**" to mean matching across path
> components which is what rsync does:
>
>  o  a '*' matches any non-empty path component (it stops at slashes).
>  o  use '**' to match anything, including slashes.
>
> ?

I personally do not think that makes much sense (and I find ** ugly, too).

We traditionally supported '*' only at the end, and it always has meant
"match through the end, including slashes".

Requiring 'match including slashes' to be spelled as '**' only when it is
not at the end is unnecessarily confusing.

Is there a valid use case when * wants to match across directory
boundaries when it is not at the end?  I offhand do not think of a sane
one.

So, it might make it easiest to understand if we say * usually does not
match slash, except when it is used at the end immediately after a slash,
in which case it means "match through the end".

^ permalink raw reply

* RE: proper way to merge?
From: John Dlugosz @ 2009-03-02 22:19 UTC (permalink / raw)
  To: John Tapsell; +Cc: git
In-Reply-To: <43d8ce650902272358h4219f439qfa60ba7a7e0d222f@mail.gmail.com>

===Re:===
Instead of merge, I prefer to rebase.  so:

git checkout dev
git rebase origin rel

This replays each commit made in 'dev' on top of release, letting you
fix each commit separately.  It also means that when I commit to
release, the changes are a nice tree.
===end===

The reason I'm doing this -- why I took over maintenance of the repository -- is because I strenuously objected to his plan to "rebase".  NO!  Merge, don't rebase.  Besides never rebasing published branches, in this case it works much better the other way around:  dev made systemic changes, and rel is mostly patches and completely new pieces of code.  After looking at what was in dev..rel and what was in rel..dev, I chose to start with dev and bring in the commits from rel in a controlled manner.

I think you are indicated that the rebase is easier because the merge is done one commit at a time rather than in one huge bang.  I want to have that advantage and then some by picking related groups of commits and verifying that it still compiles before getting more, not even limited to the original order.

I'll post what I learned in a separate note.

--John
(excuse the footer; it's not my choice)


TradeStation Group, Inc. is a publicly-traded holding company (NASDAQ GS: TRAD) of three operating subsidiaries, TradeStation Securities, Inc. (Member NYSE, FINRA, SIPC and NFA), TradeStation Technologies, Inc., a trading software and subscription company, and TradeStation Europe Limited, a United Kingdom, FSA-authorized introducing brokerage firm. None of these companies provides trading or investment advice, recommendations or endorsements of any kind. The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any computer.

^ permalink raw reply

* [PATCH] git-clone: Add option --branch to override initial branch
From: Tor Arne Vestbø @ 2009-03-02 22:11 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

The options --branch and -b allow the user to override the initial
branch created and checked out by git-clone. Normally this is the
active branch of the remote repository, which is also the fallback
if the selected branch is not found.

Signed-off-by: Tor Arne Vestbø <torarnv@gmail.com>
---
 Documentation/git-clone.txt |    5 +++++
 builtin-clone.c             |   33 +++++++++++++++++++++++++++++----
 2 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 95f08b9..e7feb4d 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -119,6 +119,11 @@ then the cloned repository will become corrupt.
 	Instead of using the remote name 'origin' to keep track
 	of the upstream repository, use <name> instead.
 
+--branch <name>::
+-b <name>::
+	Instead of using the remote repository's active branch as the
+	initial branch, use <name> instead.
+
 --upload-pack <upload-pack>::
 -u <upload-pack>::
 	When given, and the repository to clone from is accessed
diff --git a/builtin-clone.c b/builtin-clone.c
index c338910..601c2c2 100644
--- a/builtin-clone.c
+++ b/builtin-clone.c
@@ -38,6 +38,7 @@ static int option_quiet, option_no_checkout, option_bare, option_mirror;
 static int option_local, option_no_hardlinks, option_shared;
 static char *option_template, *option_reference, *option_depth;
 static char *option_origin = NULL;
+static char *option_branch = NULL;
 static char *option_upload_pack = "git-upload-pack";
 static int option_verbose;
 
@@ -66,6 +67,8 @@ static struct option builtin_clone_options[] = {
 		   "path to git-upload-pack on the remote"),
 	OPT_STRING(0, "depth", &option_depth, "depth",
 		    "create a shallow clone of that depth"),
+	OPT_STRING('b', "branch", &option_branch, "branch",
+		    "initial remote branch to check out"),
 
 	OPT_END()
 };
@@ -372,7 +375,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	const char *repo_name, *repo, *work_tree, *git_dir;
 	char *path, *dir;
 	int dest_exists;
-	const struct ref *refs, *head_points_at, *remote_head, *mapped_refs;
+	const struct ref *refs, *mapped_refs;
+	const struct ref *remote_head = NULL;
+	const struct ref *head_points_at = NULL;
 	struct strbuf key = STRBUF_INIT, value = STRBUF_INIT;
 	struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT;
 	struct transport *transport = NULL;
@@ -545,12 +550,32 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 
 		mapped_refs = write_remote_refs(refs, &refspec, reflog_msg.buf);
 
-		head_points_at = locate_head(refs, mapped_refs, &remote_head);
+		if (option_branch) {
+		    const int offset = 11;
+		    const char *branch = option_branch;
+		    if (!prefixcmp(branch, "refs/heads/"))
+			branch += offset;
+
+		    const struct ref *r;
+		    for (r = mapped_refs; r; r = r->next) {
+			if (!strcmp(r->name + offset, branch)) {
+			    /* Override initial branch */
+			    head_points_at = r;
+			    remote_head = r;
+			    break;
+			}
+		    }
+
+		    if (!head_points_at)
+			warning("remote has no branch named '%s', "
+				"falling back to default.", option_branch);
+		}
+
+		if (!head_points_at)
+		    head_points_at = locate_head(refs, mapped_refs, &remote_head);
 	}
 	else {
 		warning("You appear to have cloned an empty repository.");
-		head_points_at = NULL;
-		remote_head = NULL;
 		option_no_checkout = 1;
 		if (!option_bare)
 			install_branch_config("master", option_origin,
-- 
1.6.2.rc2.16.gf474c.dirty

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox