git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC] make --set-upstream work for local branches not in refs/heads
@ 2014-03-04 14:07 Krzesimir Nowak
  2014-03-04 14:07 ` [PATCH] RFC: make --set-upstream work for branches not in refs/heads/ Krzesimir Nowak
  2014-03-04 19:44 ` [RFC] make --set-upstream work for local branches not in refs/heads Junio C Hamano
  0 siblings, 2 replies; 4+ messages in thread
From: Krzesimir Nowak @ 2014-03-04 14:07 UTC (permalink / raw)
  To: git; +Cc: Krzesimir Nowak

It might be possible (in "Gerrited" setups) to have local branches
outside refs/heads/, like for example in following fetch config:

[remote "origin"]
	url = ssh://user@example.com/my-project
	fetch = +refs/heads/*:refs/remotes/origin/*
	fetch = +refs/wip/*:refs/remotes/origin-wip/*

Let's say that 'test' branch already exist in origin/refs/wip/. If I
call:

git checkout test

then it will create a new branch and add an entry to .git/config:

[branch "test"]
	remote = origin
	merge = refs/wip/test

But if I create a branch 'test2' and call:

git push --set-upstream origin test2:refs/wip/test2

then branch is pushed, but no entry in .git config is created. I have
to do it manually. I attached a hack-patch to have it working just to
check with you if anything like that would be accepted. Obviously the
get_local_refs() would need to compute the actual list of local
hierarchies (if it is possible at all). And it probably should get a
better name. And probably something else.

What do you think?

Krzesimir Nowak (1):
  RFC: make --set-upstream work for branches not in refs/heads/

 transport.c | 41 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 34 insertions(+), 7 deletions(-)

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH] RFC: make --set-upstream work for branches not in refs/heads/
  2014-03-04 14:07 [RFC] make --set-upstream work for local branches not in refs/heads Krzesimir Nowak
@ 2014-03-04 14:07 ` Krzesimir Nowak
  2014-03-04 19:44 ` [RFC] make --set-upstream work for local branches not in refs/heads Junio C Hamano
  1 sibling, 0 replies; 4+ messages in thread
From: Krzesimir Nowak @ 2014-03-04 14:07 UTC (permalink / raw)
  To: git; +Cc: Krzesimir Nowak

---
 transport.c | 41 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 34 insertions(+), 7 deletions(-)

diff --git a/transport.c b/transport.c
index ca7bb44..ac933ee 100644
--- a/transport.c
+++ b/transport.c
@@ -143,6 +143,25 @@ static void insert_packed_refs(const char *packed_refs, struct ref **list)
 	}
 }
 
+/* That of course should not be hardcoded. */
+static const char* list_of_local_refs[] = {"refs/heads/", "refs/wip/", NULL};
+static const char** get_local_refs(void)
+{
+	return list_of_local_refs;
+}
+
+static int is_local_ref(const char *ref)
+{
+	const char **local_refs = get_local_refs();
+	const char **iter;
+
+	for (iter = local_refs; iter != NULL; ++iter)
+		if (starts_with(ref, *iter))
+			return strlen(*iter);
+
+	return 0;
+}
+
 static void set_upstreams(struct transport *transport, struct ref *refs,
 	int pretend)
 {
@@ -153,6 +172,8 @@ static void set_upstreams(struct transport *transport, struct ref *refs,
 		const char *remotename;
 		unsigned char sha[20];
 		int flag = 0;
+		int localadd = 0;
+		int remoteadd = 0;
 		/*
 		 * Check suitability for tracking. Must be successful /
 		 * already up-to-date ref create/modify (not delete).
@@ -169,23 +190,29 @@ static void set_upstreams(struct transport *transport, struct ref *refs,
 		localname = ref->peer_ref->name;
 		remotename = ref->name;
 		tmp = resolve_ref_unsafe(localname, sha, 1, &flag);
-		if (tmp && flag & REF_ISSYMREF &&
-			starts_with(tmp, "refs/heads/"))
-			localname = tmp;
+
+		if (tmp && flag & REF_ISSYMREF) {
+			localadd = is_local_ref (tmp);
+			if (localadd > 0)
+				localname = tmp;
+		}
+		if (localadd == 0)
+			localadd = is_local_ref(localname);
+		remoteadd = is_local_ref(remotename);
 
 		/* Both source and destination must be local branches. */
-		if (!localname || !starts_with(localname, "refs/heads/"))
+		if (!localname || localadd == 0)
 			continue;
-		if (!remotename || !starts_with(remotename, "refs/heads/"))
+		if (!remotename || remoteadd == 0)
 			continue;
 
 		if (!pretend)
 			install_branch_config(BRANCH_CONFIG_VERBOSE,
-				localname + 11, transport->remote->name,
+				localname + localadd, transport->remote->name,
 				remotename);
 		else
 			printf("Would set upstream of '%s' to '%s' of '%s'\n",
-				localname + 11, remotename + 11,
+				localname + localadd, remotename + remoteadd,
 				transport->remote->name);
 	}
 }
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [RFC] make --set-upstream work for local branches not in refs/heads
  2014-03-04 14:07 [RFC] make --set-upstream work for local branches not in refs/heads Krzesimir Nowak
  2014-03-04 14:07 ` [PATCH] RFC: make --set-upstream work for branches not in refs/heads/ Krzesimir Nowak
@ 2014-03-04 19:44 ` Junio C Hamano
  2014-03-06  9:27   ` Krzesimir Nowak
  1 sibling, 1 reply; 4+ messages in thread
From: Junio C Hamano @ 2014-03-04 19:44 UTC (permalink / raw)
  To: Krzesimir Nowak; +Cc: git

Krzesimir Nowak <krzesimir@endocode.com> writes:

> It might be possible (in "Gerrited" setups) to have local branches
> outside refs/heads/, like for example in following fetch config:
>
> [remote "origin"]
> 	url = ssh://user@example.com/my-project
> 	fetch = +refs/heads/*:refs/remotes/origin/*
> 	fetch = +refs/wip/*:refs/remotes/origin-wip/*
>
> Let's say that 'test' branch already exist in origin/refs/wip/. If I
> call:
>
> git checkout test
>
> then it will create a new branch and add an entry to .git/config:
>
> [branch "test"]
> 	remote = origin
> 	merge = refs/wip/test
>
> But if I create a branch 'test2' and call:
>
> git push --set-upstream origin test2:refs/wip/test2
>
> then branch is pushed, but no entry in .git config is created.

By definition anything otuside refs/heads/ is not a branch, so do
not call things in refs/wip "branches".  Retitle it to "work for
local refs outside refs/heads" or something.

Having said that, I do not see a major problem if we allowed

	[branch "test2"]
		remote = origin
                merge = refs/wip/test2

to be created when "push --setupstream" is requested, making
test2@{upstream} to point at refs/remotes/origin-wip/test2.

I do not know what the correct implementation of such a feature
should be, though.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC] make --set-upstream work for local branches not in refs/heads
  2014-03-04 19:44 ` [RFC] make --set-upstream work for local branches not in refs/heads Junio C Hamano
@ 2014-03-06  9:27   ` Krzesimir Nowak
  0 siblings, 0 replies; 4+ messages in thread
From: Krzesimir Nowak @ 2014-03-06  9:27 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Tue, 2014-03-04 at 11:44 -0800, Junio C Hamano wrote:
> Krzesimir Nowak <krzesimir@endocode.com> writes:
> 
> > It might be possible (in "Gerrited" setups) to have local branches
> > outside refs/heads/, like for example in following fetch config:
> >
> > [remote "origin"]
> > 	url = ssh://user@example.com/my-project
> > 	fetch = +refs/heads/*:refs/remotes/origin/*
> > 	fetch = +refs/wip/*:refs/remotes/origin-wip/*
> >
> > Let's say that 'test' branch already exist in origin/refs/wip/. If I
> > call:
> >
> > git checkout test
> >
> > then it will create a new branch and add an entry to .git/config:
> >
> > [branch "test"]
> > 	remote = origin
> > 	merge = refs/wip/test
> >
> > But if I create a branch 'test2' and call:
> >
> > git push --set-upstream origin test2:refs/wip/test2
> >
> > then branch is pushed, but no entry in .git config is created.
> 
> By definition anything otuside refs/heads/ is not a branch, so do
> not call things in refs/wip "branches".  Retitle it to "work for
> local refs outside refs/heads" or something.

I always have problems with proper use of git's terminology. Sorry.

> 
> Having said that, I do not see a major problem if we allowed
> 
> 	[branch "test2"]
> 		remote = origin
>                 merge = refs/wip/test2
> 
> to be created when "push --setupstream" is requested, making
> test2@{upstream} to point at refs/remotes/origin-wip/test2.
> 
> I do not know what the correct implementation of such a feature
> should be, though.

Hm, have some idea about it, though I will leave its sanity to judge to
you.

Given the following config snippet:
[remote "origin"]
	url = ssh://user@example.com/my-project
	fetch = +refs/heads/*:refs/remotes/origin/*
	fetch = +refs/wip/*:refs/remotes/origin-wip/*

We could have get_local_ref_hierarchies function defined somewhat as
follows (memory management details are left out):

char **get_local_ref_hierarchies(char *remote)
{
	char **refspecs = get_fetch_refspecs_for_remote (remote);
	char **iter;
	char **local = NULL;

	for (iter = refspecs; iter && *iter; ++iter) {
		char *src = get_src_refspec_part (*iter);
		push (&local, src);
	}

	/* maybe filter dups and make refs/heads/ first */
	return local;
}

I'm sure that there are some corner-cases this code does not handle.

Also, maybe it would be good to add some information when --set-upstream
does nothing. Something like after doing "git push --set-upstream origin
test:refs/wip/test":

"""
Could not set temp to track refs/wip/test. Either call:
git config branch.test.remote origin
git config branch.test.merge refs/wip/test

or (this part would appear if this solution in patch is accepted)

git config --add remote.origin.fetch \
"+refs/wip/*:refs/remotes/origin-wip/*
"""

Cheers,
-- 
Krzesimir Nowak
Software Developer
Endocode AG

krzesimir@endocode.com

------
Endocode AG, Johannisstraße 20, 10117 Berlin
info@endocode.com | www.endocode.com

Vorstandsvorsitzender: Mirko Boehm
Vorstände: Dr. Karl Beecher, Chris Kühl, Sebastian Sucker
Aufsichtsratsvorsitzende: Jennifer Beecher

Registergericht: Amtsgericht Charlottenburg - HRB 150748 B

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-03-06  9:27 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-04 14:07 [RFC] make --set-upstream work for local branches not in refs/heads Krzesimir Nowak
2014-03-04 14:07 ` [PATCH] RFC: make --set-upstream work for branches not in refs/heads/ Krzesimir Nowak
2014-03-04 19:44 ` [RFC] make --set-upstream work for local branches not in refs/heads Junio C Hamano
2014-03-06  9:27   ` Krzesimir Nowak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).