* [RFC PATCH 2/2] new --rebase option to set branch.*.rebase for new branches
2008-02-16 3:45 [RFC PATCH 1/2] git-branch: allow --track to work w/local branches Jay Soffian
@ 2008-02-16 3:45 ` Jay Soffian
2008-02-16 5:10 ` [RFC PATCH 1/2] git-branch: allow --track to work w/local branches Junio C Hamano
1 sibling, 0 replies; 6+ messages in thread
From: Jay Soffian @ 2008-02-16 3:45 UTC (permalink / raw)
To: git; +Cc: Jay Soffian
Add a --rebase option to git-branch and git-checkout. If given, it
implies --track but additionally sets branch.<newbranch>.rebase to true.
Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
---
builtin-branch.c | 18 ++++++++++++++----
git-checkout.sh | 11 ++++++++---
2 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/builtin-branch.c b/builtin-branch.c
index 94ab195..1404d8b 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -393,7 +393,7 @@ static int find_tracked_branch(struct remote *remote, void *priv)
* to infer the settings for branch.<new_ref>.{remote,merge} from the
* config.
*/
-static int setup_tracking(const char *new_ref, const char *orig_ref)
+static int setup_tracking(const char *new_ref, const char *orig_ref, int rebase)
{
char key[1024];
struct tracking tracking;
@@ -407,6 +407,10 @@ static int setup_tracking(const char *new_ref, const char *orig_ref)
git_config_set(key, ".");
sprintf(key, "branch.%s.merge", new_ref);
git_config_set(key, orig_ref);
+ if (rebase) {
+ sprintf(key, "branch.%s.rebase", new_ref);
+ git_config_set(key, "true");
+ }
printf("Branch %s set up to track local branch %s.\n",
new_ref, orig_ref);
return 0;
@@ -428,6 +432,10 @@ static int setup_tracking(const char *new_ref, const char *orig_ref)
sprintf(key, "branch.%s.merge", new_ref);
git_config_set(key, tracking.src);
free(tracking.src);
+ if (rebase) {
+ sprintf(key, "branch.%s.rebase", new_ref);
+ git_config_set(key, "true");
+ }
printf("Branch %s set up to track remote branch %s.\n",
new_ref, orig_ref);
}
@@ -436,7 +444,7 @@ static int setup_tracking(const char *new_ref, const char *orig_ref)
}
static void create_branch(const char *name, const char *start_name,
- int force, int reflog, int track)
+ int force, int reflog, int track, int rebase)
{
struct ref_lock *lock;
struct commit *commit;
@@ -495,7 +503,7 @@ static void create_branch(const char *name, const char *start_name,
automatically merges from there. So far, this is only done for
remotes registered via .git/config. */
if (real_ref && track)
- setup_tracking(name, real_ref);
+ setup_tracking(name, real_ref, rebase);
if (write_ref_sha1(lock, sha1, msg) < 0)
die("Failed to write ref: %s.", strerror(errno));
@@ -566,12 +574,14 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
int verbose = 0, abbrev = DEFAULT_ABBREV, detached = 0;
int reflog = 0, track;
int kinds = REF_LOCAL_BRANCH;
+ int rebase = 0;
struct commit_list *with_commit = NULL;
struct option options[] = {
OPT_GROUP("Generic options"),
OPT__VERBOSE(&verbose),
OPT_BOOLEAN( 0 , "track", &track, "set up tracking mode (see git-pull(1))"),
+ OPT_BOOLEAN( 0 , "rebase", &rebase, "set up branch to rebase (see git-pull(1))"),
OPT_BOOLEAN( 0 , "color", &branch_use_color, "use colored output"),
OPT_SET_INT('r', NULL, &kinds, "act on remote-tracking branches",
REF_REMOTE_BRANCH),
@@ -625,7 +635,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
rename_branch(argv[0], argv[1], rename > 1);
else if (argc <= 2)
create_branch(argv[0], (argc == 2) ? argv[1] : head,
- force_create, reflog, track);
+ force_create, reflog, track, rebase);
else
usage_with_options(builtin_branch_usage, options);
diff --git a/git-checkout.sh b/git-checkout.sh
index bd74d70..569e29c 100755
--- a/git-checkout.sh
+++ b/git-checkout.sh
@@ -7,6 +7,7 @@ git-checkout [options] [<branch>] [<paths>...]
b= create a new branch started at <branch>
l create the new branch's reflog
track arrange that the new branch tracks the remote branch
+rebase arrange that the new branch rebases
f proceed even if the index or working tree is not HEAD
m merge local modifications into the new branch
q,quiet be quiet
@@ -23,6 +24,7 @@ new_name=
force=
branch=
track=
+rebase=
newbranch=
newbranch_log=
merge=
@@ -49,6 +51,9 @@ while test $# != 0; do
--track|--no-track)
track="$1"
;;
+ --rebase)
+ rebase="$1"
+ ;;
-f)
force=1
;;
@@ -92,9 +97,9 @@ then
fi
[ "$1" = "--" ] && shift
-case "$newbranch,$track" in
+case "$newbranch,$track,$rebase" in
,--*)
- die "git checkout: --track and --no-track require -b"
+ die "git checkout: --track, --no-track and --rebase require -b"
esac
case "$force$merge" in
@@ -261,7 +266,7 @@ fi
#
if [ "$?" -eq 0 ]; then
if [ "$newbranch" ]; then
- git branch $track $newbranch_log "$newbranch" "$new_name" || exit
+ git branch $track $rebase $newbranch_log "$newbranch" "$new_name" || exit
branch="$newbranch"
fi
if test -n "$branch"
--
1.5.4.1.1281.g75df
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [RFC PATCH 1/2] git-branch: allow --track to work w/local branches
2008-02-16 3:45 [RFC PATCH 1/2] git-branch: allow --track to work w/local branches Jay Soffian
2008-02-16 3:45 ` [RFC PATCH 2/2] new --rebase option to set branch.*.rebase for new branches Jay Soffian
@ 2008-02-16 5:10 ` Junio C Hamano
2008-02-16 7:07 ` Jay Soffian
2008-02-16 11:45 ` Johannes Schindelin
1 sibling, 2 replies; 6+ messages in thread
From: Junio C Hamano @ 2008-02-16 5:10 UTC (permalink / raw)
To: Jay Soffian; +Cc: git, Johannes Schindelin
Jay Soffian <jaysoffian@gmail.com> writes:
> diff --git a/builtin-branch.c b/builtin-branch.c
> index e414c88..94ab195 100644
> --- a/builtin-branch.c
> +++ b/builtin-branch.c
> @@ -402,6 +402,16 @@ static int setup_tracking(const char *new_ref, const char *orig_ref)
> return error("Tracking not set up: name too long: %s",
> new_ref);
>
> + if (!prefixcmp(orig_ref, "refs/heads/")) {
> + sprintf(key, "branch.%s.remote", new_ref);
> + git_config_set(key, ".");
> + sprintf(key, "branch.%s.merge", new_ref);
> + git_config_set(key, orig_ref);
> + printf("Branch %s set up to track local branch %s.\n",
> + new_ref, orig_ref);
> + return 0;
> + }
> +
> memset(&tracking, 0, sizeof(tracking));
> tracking.spec.dst = (char *)orig_ref;
> if (for_each_remote(find_tracked_branch, &tracking) ||
Although I am not so familiar with this area, the patch somehow
did not feel right, so I ended up doing a bit of digging.
After the context of the patch, we have this:
if (tracking.matches == 1) {
sprintf(key, "branch.%s.remote", new_ref);
git_config_set(key, tracking.remote ? tracking.remote : ".");
sprintf(key, "branch.%s.merge", new_ref);
git_config_set(key, tracking.src);
So it looks to me that the code already has intention to set the
"branch.*.remote" variable to "." when certain condition is met.
And the condition is "when tracking.remote is NULL, or it is
already a dot".
for_each_remote() iterates thru the remotes and
find_tracked_branch() does this:
static int find_tracked_branch(struct remote *remote, void *priv)
{
struct tracking *tracking = priv;
if (!remote_find_tracking(remote, &tracking->spec)) {
if (++tracking->matches == 1) {
tracking->src = tracking->spec.src;
tracking->remote = remote->name;
} else {
free(tracking->spec.src);
if (tracking->src) {
free(tracking->src);
tracking->src = NULL;
}
}
tracking->spec.src = NULL;
}
return 0;
}
So if there is a remote whose name is "." (or NULL, but I do not
know when that can happen --- remote.c::make_remote() does not
allow creating such a remote as far as I can tell), that would
be found without the added extra code, wouldn't it?
I did a bit of experiment and with this in .git/config:
[remote "."]
fetch = refs/*:refs/*
it turns out that you do not have to patch the code at all. The
above manual configuration feels somewhat like an ugly hack but
perhaps we should make the above two lines implied? This area
was last cleaned up in 6f084a5 (branch --track: code cleanup and
saner handling of local branches). I do not know if the
original intention of the code was to allow a hack like this to
work, or it is just an unintended accident that it happens to
work. Dscho, any ideas?
^ permalink raw reply [flat|nested] 6+ messages in thread