Allow tracking branches to set up rebase by default.
Change cd67e4d4 introduced a new configuration parameter that told pull to automatically perform a rebase instead of a merge. This change provides a configuration option to enable this feature automatically when creating a new branch. If the variable branch.autosetuprebase applies for a branch that's being created, that branch will have branch.<name>.rebase set to true. Signed-off-by: Dustin Sallings <dustin@spy.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Dustin Sallings committed
May 10, 2008 at 15:36 UTC
0a02186f924aee1bd69f18ed01f645aa332ce0d1
6 files changed
+294
-1
Documentation/config.txt
+15
@@ -399,6 +399,21 @@ branch.autosetupmerge::
399
done when the starting point is either a local branch or remote
400
branch. This option defaults to true.
401
402
+branch.autosetuprebase::
403
+ When a new branch is created with `git-branch` or `git-checkout`
404
+ that tracks another branch, this variable tells git to set
405
+ up pull to rebase instead of merge (see "branch.<name>.rebase").
406
+ When `never`, rebase is never automatically set to true.
407
+ When `local`, rebase is set to true for tracked branches of
408
+ other local branches.
409
+ When `remote`, rebase is set to true for tracked branches of
410
+ remote branches.
411
+ When `always`, rebase will be set to true for all tracking
412
+ branches.
413
+ See "branch.autosetupmerge" for details on how to set up a
414
+ branch to track another branch.
415
+ This option defaults to never.
416
+
417
branch.<name>.remote::
418
When in branch <name>, it tells `git fetch` which remote to fetch.
419
If this option is not given, `git fetch` defaults to remote "origin".
branch.c
+21
-1
@@ -32,6 +32,21 @@ static int find_tracked_branch(struct remote *remote, void *priv)
32
return 0;
33
}
34
35
+static int should_setup_rebase(const struct tracking *tracking)
36
+{
37
+ switch (autorebase) {
38
+ case AUTOREBASE_NEVER:
39
+ return 0;
40
+ case AUTOREBASE_LOCAL:
41
+ return tracking->remote == NULL;
42
+ case AUTOREBASE_REMOTE:
43
+ return tracking->remote != NULL;
44
+ case AUTOREBASE_ALWAYS:
45
+ return 1;
46
+ }
47
+ return 0;
48
+}
49
+
50
/*
51
* This is called when new_ref is branched off of orig_ref, and tries
52
* to infer the settings for branch.<new_ref>.{remote,merge} from the
@@ -69,9 +84,14 @@ static int setup_tracking(const char *new_ref, const char *orig_ref,
84
git_config_set(key, tracking.remote ? tracking.remote : ".");
85
sprintf(key, "branch.%s.merge", new_ref);
86
git_config_set(key, tracking.src ? tracking.src : orig_ref);
72
- free(tracking.src);
87
printf("Branch %s set up to track %s branch %s.\n", new_ref,
88
tracking.remote ? "remote" : "local", orig_ref);
89
+ if (should_setup_rebase(&tracking)) {
90
+ sprintf(key, "branch.%s.rebase", new_ref);
91
+ git_config_set(key, "true");
92
+ printf("This branch will rebase on pull.\n");
93
+ }
94
+ free(tracking.src);
95
96
return 0;
97
}
cache.h
+8
@@ -434,7 +434,15 @@ enum branch_track {
434
BRANCH_TRACK_EXPLICIT,
435
};
436
437
+enum rebase_setup_type {
438
+ AUTOREBASE_NEVER = 0,
439
+ AUTOREBASE_LOCAL,
440
+ AUTOREBASE_REMOTE,
441
+ AUTOREBASE_ALWAYS,
442
+};
443
+
444
extern enum branch_track git_branch_track;
445
+extern enum rebase_setup_type autorebase;
446
447
#define GIT_REPO_VERSION 0
448
extern int repository_format_version;
config.c
+15
@@ -487,6 +487,21 @@ int git_default_config(const char *var, const char *value)
487
git_branch_track = git_config_bool(var, value);
488
return 0;
489
}
490
+ if (!strcmp(var, "branch.autosetuprebase")) {
491
+ if (!value)
492
+ return config_error_nonbool(var);
493
+ else if (!strcmp(value, "never"))
494
+ autorebase = AUTOREBASE_NEVER;
495
+ else if (!strcmp(value, "local"))
496
+ autorebase = AUTOREBASE_LOCAL;
497
+ else if (!strcmp(value, "remote"))
498
+ autorebase = AUTOREBASE_REMOTE;
499
+ else if (!strcmp(value, "always"))
500
+ autorebase = AUTOREBASE_ALWAYS;
501
+ else
502
+ return error("Malformed value for %s", var);
503
+ return 0;
504
+ }
505
506
/* Add other config variables here and to Documentation/config.txt. */
507
return 0;
environment.c
+1
@@ -38,6 +38,7 @@ int auto_crlf = 0; /* 1: both ways, -1: only when adding git objects */
38
enum safe_crlf safe_crlf = SAFE_CRLF_WARN;
39
unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
40
enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;
41
+enum rebase_setup_type autorebase = AUTOREBASE_NEVER;
42
43
/* This is set by setup_git_dir_gently() and/or git_default_config() */
44
char *git_work_tree_cfg;
t/t3200-branch.sh
+234
@@ -224,4 +224,238 @@ test_expect_success 'avoid ambiguous track' '
224
test -z "$(git config branch.all1.merge)"
225
'
226
227
+test_expect_success 'autosetuprebase local on a tracked local branch' '
228
+ git config remote.local.url . &&
229
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
230
+ git config branch.autosetuprebase local &&
231
+ (git show-ref -q refs/remotes/local/o || git-fetch local) &&
232
+ git branch mybase &&
233
+ git branch --track myr1 mybase &&
234
+ test "$(git config branch.myr1.remote)" = . &&
235
+ test "$(git config branch.myr1.merge)" = refs/heads/mybase &&
236
+ test "$(git config branch.myr1.rebase)" = true
237
+'
238
+
239
+test_expect_success 'autosetuprebase always on a tracked local branch' '
240
+ git config remote.local.url . &&
241
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
242
+ git config branch.autosetuprebase always &&
243
+ (git show-ref -q refs/remotes/local/o || git-fetch local) &&
244
+ git branch mybase2 &&
245
+ git branch --track myr2 mybase &&
246
+ test "$(git config branch.myr2.remote)" = . &&
247
+ test "$(git config branch.myr2.merge)" = refs/heads/mybase &&
248
+ test "$(git config branch.myr2.rebase)" = true
249
+'
250
+
251
+test_expect_success 'autosetuprebase remote on a tracked local branch' '
252
+ git config remote.local.url . &&
253
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
254
+ git config branch.autosetuprebase remote &&
255
+ (git show-ref -q refs/remotes/local/o || git-fetch local) &&
256
+ git branch mybase3 &&
257
+ git branch --track myr3 mybase2 &&
258
+ test "$(git config branch.myr3.remote)" = . &&
259
+ test "$(git config branch.myr3.merge)" = refs/heads/mybase2 &&
260
+ ! test "$(git config branch.myr3.rebase)" = true
261
+'
262
+
263
+test_expect_success 'autosetuprebase never on a tracked local branch' '
264
+ git config remote.local.url . &&
265
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
266
+ git config branch.autosetuprebase never &&
267
+ (git show-ref -q refs/remotes/local/o || git-fetch local) &&
268
+ git branch mybase4 &&
269
+ git branch --track myr4 mybase2 &&
270
+ test "$(git config branch.myr4.remote)" = . &&
271
+ test "$(git config branch.myr4.merge)" = refs/heads/mybase2 &&
272
+ ! test "$(git config branch.myr4.rebase)" = true
273
+'
274
+
275
+test_expect_success 'autosetuprebase local on a tracked remote branch' '
276
+ git config remote.local.url . &&
277
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
278
+ git config branch.autosetuprebase local &&
279
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
280
+ git branch --track myr5 local/master &&
281
+ test "$(git config branch.myr5.remote)" = local &&
282
+ test "$(git config branch.myr5.merge)" = refs/heads/master &&
283
+ ! test "$(git config branch.myr5.rebase)" = true
284
+'
285
+
286
+test_expect_success 'autosetuprebase never on a tracked remote branch' '
287
+ git config remote.local.url . &&
288
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
289
+ git config branch.autosetuprebase never &&
290
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
291
+ git branch --track myr6 local/master &&
292
+ test "$(git config branch.myr6.remote)" = local &&
293
+ test "$(git config branch.myr6.merge)" = refs/heads/master &&
294
+ ! test "$(git config branch.myr6.rebase)" = true
295
+'
296
+
297
+test_expect_success 'autosetuprebase remote on a tracked remote branch' '
298
+ git config remote.local.url . &&
299
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
300
+ git config branch.autosetuprebase remote &&
301
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
302
+ git branch --track myr7 local/master &&
303
+ test "$(git config branch.myr7.remote)" = local &&
304
+ test "$(git config branch.myr7.merge)" = refs/heads/master &&
305
+ test "$(git config branch.myr7.rebase)" = true
306
+'
307
+
308
+test_expect_success 'autosetuprebase always on a tracked remote branch' '
309
+ git config remote.local.url . &&
310
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
311
+ git config branch.autosetuprebase remote &&
312
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
313
+ git branch --track myr8 local/master &&
314
+ test "$(git config branch.myr8.remote)" = local &&
315
+ test "$(git config branch.myr8.merge)" = refs/heads/master &&
316
+ test "$(git config branch.myr8.rebase)" = true
317
+'
318
+
319
+test_expect_success 'autosetuprebase unconfigured on a tracked remote branch' '
320
+ git config --unset branch.autosetuprebase &&
321
+ git config remote.local.url . &&
322
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
323
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
324
+ git branch --track myr9 local/master &&
325
+ test "$(git config branch.myr9.remote)" = local &&
326
+ test "$(git config branch.myr9.merge)" = refs/heads/master &&
327
+ test "z$(git config branch.myr9.rebase)" = z
328
+'
329
+
330
+test_expect_success 'autosetuprebase unconfigured on a tracked local branch' '
331
+ git config remote.local.url . &&
332
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
333
+ (git show-ref -q refs/remotes/local/o || git-fetch local) &&
334
+ git branch mybase10 &&
335
+ git branch --track myr10 mybase2 &&
336
+ test "$(git config branch.myr10.remote)" = . &&
337
+ test "$(git config branch.myr10.merge)" = refs/heads/mybase2 &&
338
+ test "z$(git config branch.myr10.rebase)" = z
339
+'
340
+
341
+test_expect_success 'autosetuprebase unconfigured on untracked local branch' '
342
+ git config remote.local.url . &&
343
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
344
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
345
+ git branch --no-track myr11 mybase2 &&
346
+ test "z$(git config branch.myr11.remote)" = z &&
347
+ test "z$(git config branch.myr11.merge)" = z &&
348
+ test "z$(git config branch.myr11.rebase)" = z
349
+'
350
+
351
+test_expect_success 'autosetuprebase unconfigured on untracked remote branch' '
352
+ git config remote.local.url . &&
353
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
354
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
355
+ git branch --no-track myr12 local/master &&
356
+ test "z$(git config branch.myr12.remote)" = z &&
357
+ test "z$(git config branch.myr12.merge)" = z &&
358
+ test "z$(git config branch.myr12.rebase)" = z
359
+'
360
+
361
+test_expect_success 'autosetuprebase never on an untracked local branch' '
362
+ git config branch.autosetuprebase never &&
363
+ git config remote.local.url . &&
364
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
365
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
366
+ git branch --no-track myr13 mybase2 &&
367
+ test "z$(git config branch.myr13.remote)" = z &&
368
+ test "z$(git config branch.myr13.merge)" = z &&
369
+ test "z$(git config branch.myr13.rebase)" = z
370
+'
371
+
372
+test_expect_success 'autosetuprebase local on an untracked local branch' '
373
+ git config branch.autosetuprebase local &&
374
+ git config remote.local.url . &&
375
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
376
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
377
+ git branch --no-track myr14 mybase2 &&
378
+ test "z$(git config branch.myr14.remote)" = z &&
379
+ test "z$(git config branch.myr14.merge)" = z &&
380
+ test "z$(git config branch.myr14.rebase)" = z
381
+'
382
+
383
+test_expect_success 'autosetuprebase remote on an untracked local branch' '
384
+ git config branch.autosetuprebase remote &&
385
+ git config remote.local.url . &&
386
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
387
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
388
+ git branch --no-track myr15 mybase2 &&
389
+ test "z$(git config branch.myr15.remote)" = z &&
390
+ test "z$(git config branch.myr15.merge)" = z &&
391
+ test "z$(git config branch.myr15.rebase)" = z
392
+'
393
+
394
+test_expect_success 'autosetuprebase always on an untracked local branch' '
395
+ git config branch.autosetuprebase always &&
396
+ git config remote.local.url . &&
397
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
398
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
399
+ git branch --no-track myr16 mybase2 &&
400
+ test "z$(git config branch.myr16.remote)" = z &&
401
+ test "z$(git config branch.myr16.merge)" = z &&
402
+ test "z$(git config branch.myr16.rebase)" = z
403
+'
404
+
405
+test_expect_success 'autosetuprebase never on an untracked remote branch' '
406
+ git config branch.autosetuprebase never &&
407
+ git config remote.local.url . &&
408
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
409
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
410
+ git branch --no-track myr17 local/master &&
411
+ test "z$(git config branch.myr17.remote)" = z &&
412
+ test "z$(git config branch.myr17.merge)" = z &&
413
+ test "z$(git config branch.myr17.rebase)" = z
414
+'
415
+
416
+test_expect_success 'autosetuprebase local on an untracked remote branch' '
417
+ git config branch.autosetuprebase local &&
418
+ git config remote.local.url . &&
419
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
420
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
421
+ git branch --no-track myr18 local/master &&
422
+ test "z$(git config branch.myr18.remote)" = z &&
423
+ test "z$(git config branch.myr18.merge)" = z &&
424
+ test "z$(git config branch.myr18.rebase)" = z
425
+'
426
+
427
+test_expect_success 'autosetuprebase remote on an untracked remote branch' '
428
+ git config branch.autosetuprebase remote &&
429
+ git config remote.local.url . &&
430
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
431
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
432
+ git branch --no-track myr19 local/master &&
433
+ test "z$(git config branch.myr19.remote)" = z &&
434
+ test "z$(git config branch.myr19.merge)" = z &&
435
+ test "z$(git config branch.myr19.rebase)" = z
436
+'
437
+
438
+test_expect_success 'autosetuprebase always on an untracked remote branch' '
439
+ git config branch.autosetuprebase always &&
440
+ git config remote.local.url . &&
441
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
442
+ (git show-ref -q refs/remotes/local/master || git-fetch local) &&
443
+ git branch --no-track myr20 local/master &&
444
+ test "z$(git config branch.myr20.remote)" = z &&
445
+ test "z$(git config branch.myr20.merge)" = z &&
446
+ test "z$(git config branch.myr20.rebase)" = z
447
+'
448
+
449
+test_expect_success 'detect misconfigured autosetuprebase (bad value)' '
450
+ git config branch.autosetuprebase garbage &&
451
+ test_must_fail git branch
452
+'
453
+
454
+test_expect_success 'detect misconfigured autosetuprebase (no value)' '
455
+ git config --unset branch.autosetuprebase &&
456
+ echo "[branch] autosetuprebase" >> .git/config &&
457
+ test_must_fail git branch &&
458
+ git config --unset branch.autosetuprebase
459
+'
460
+
461
test_done