{"thread":{"id":"6901","subject":"[PATCH] Rework of the 'stg pull' policy.","startedAt":"2007-02-20T23:16:11Z","lastAt":"2007-02-20T23:16:11Z","messageCount":1,"participants":["Yann Dirson"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"35145","messageId":"20070220231407.3194.1053.stgit@gandelf.nowhere.earth","threadId":"6901","inReplyTo":null,"subject":"[PATCH] Rework of the 'stg pull' policy.","fromName":"Yann Dirson","fromEmail":"ydirson@altern.org","sentAt":"2007-02-20T23:16:11Z","receivedAt":"2007-02-20T23:16:11Z","isPatch":true,"sender":{"key":"ydirson@altern.org","avatar":"https://avatars.githubusercontent.com/u/1190950?v=4"},"body":"\nThis patch changes the way \"stg pull\" behaviour is selected, by\nreplacing stgit.pull-does-rebase and stgit.pullcmd with\nstgit.pull-policy, stgit.pullcmd and stgit.fetchcmd.  In the standard\ncase, only pull-policy needs to be set.\n\nThose 3 config variables are also available per-branch as\nbranch.*.stgit.<name>.\n\nThis patch also add a set of tests for the fetch-rebase policy,\nincluding interferences with \"stg commit\" occuring with 0.12.\n\nSigned-off-by: Yann Dirson <ydirson@altern.org>\n---\n\nThis is an implementation of the solution described in my previous\nmail.\n\n examples/gitconfig           |   17 ++++++----\n stgit/commands/pull.py       |   23 +++++++++++--\n stgit/config.py              |    5 ++-\n stgit/git.py                 |   19 +++++++++++\n t/t2100-pull-policy-fetch.sh |   72 ++++++++++++++++++++++++++++++++++++++++++\n 5 files changed, 123 insertions(+), 13 deletions(-)\n\ndiff --git a/examples/gitconfig b/examples/gitconfig\nindex 4e775fc..637f153 100644\n--- a/examples/gitconfig\n+++ b/examples/gitconfig\n@@ -33,14 +33,19 @@\n \t#pager = ~/share/stgit/contrib/diffcol.sh\n \t#pager = filterdiff --annotate | colordiff | less -FRX\n \n-\t# GIT pull command (should take the same arguments as\n+\t# GIT pull and fetch commands (should take the same arguments as\n \t# git-fetch or git-pull).  By default:\n-\t#pullcmd = git-fetch\n-\t#pull-does-rebase = yes\n-\t# Alternative (old behaviour), less intuitive but maybe useful\n-\t# for some workflows:\n \t#pullcmd = git-pull\n-\t#pull-does-rebase = no\n+\t#fetchcmd = git-fetch\n+\n+\t# \"stg pull\" policy.  This is the repository default, which can be\n+\t# overriden on a per-branch basis using branch.*.stgit.pull-policy\n+\t# By default:\n+\t#pull-policy = pull\n+\t# To support remote rewinding parent branches:\n+\t#pull-policy = fetch-rebase\n+\t# To support local parent branches:\n+\t#pull-policy = rebase\n \n \t# The three-way merge tool. Note that the 'output' file contains the\n \t# same data as 'branch1'. This is useful for tools that do not take an\ndiff --git a/stgit/commands/pull.py b/stgit/commands/pull.py\nindex 990244e..e4a2b62 100644\n--- a/stgit/commands/pull.py\n+++ b/stgit/commands/pull.py\n@@ -64,14 +64,29 @@ def func(parser, options, args):\n     check_conflicts()\n     check_head_top_equal()\n \n-    must_rebase = (config.get('stgit.pull-does-rebase') == 'yes')\n+    policy = config.get('branch.%s.stgit.pull-policy' % crt_series.get_branch()) or \\\n+             config.get('stgit.pull-policy')\n+    if policy == 'pull':\n+        must_rebase = 0\n+    elif policy == 'fetch-rebase':\n+        must_rebase = 1\n+    elif policy == 'rebase':\n+        must_rebase = 1\n+    else:\n+        raise config.ConfigException, 'Unsupported pull-policy \"%s\"' % policy\n+\n     applied = prepare_rebase(real_rebase=must_rebase, force=options.force)\n \n     # pull the remote changes\n-    print 'Pulling from \"%s\"...' % repository\n-    git.fetch(repository)\n-    if must_rebase:\n+    if policy == 'pull':\n+        print 'Pulling from \"%s\"...' % repository\n+        git.pull(repository)\n+    elif policy == 'fetch-rebase':\n+        print 'Fetching from \"%s\"...' % repository\n+        git.fetch(repository)\n         rebase(git.fetch_head())\n+    elif policy == 'rebase':\n+        rebase(crt_series.get_parent_branch())\n \n     post_rebase(applied, options.nopush, options.merged)\n \ndiff --git a/stgit/config.py b/stgit/config.py\nindex fb38932..b016fbd 100644\n--- a/stgit/config.py\n+++ b/stgit/config.py\n@@ -29,8 +29,9 @@ class GitConfig:\n         'stgit.autoresolved':\t'no',\n         'stgit.smtpserver':\t'localhost:25',\n         'stgit.smtpdelay':\t'5',\n-        'stgit.pullcmd':\t'git-fetch',\n-        'stgit.pull-does-rebase': 'yes',\n+        'stgit.pullcmd':\t'git-pull',\n+        'stgit.fetchcmd':\t'git-fetch',\n+        'stgit.pull-policy':\t'pull',\n         'stgit.merger':\t\t'diff3 -L current -L ancestor -L patched -m -E ' \\\n \t\t\t\t'\"%(branch1)s\" \"%(ancestor)s\" \"%(branch2)s\" > \"%(output)s\"',\n         'stgit.autoimerge':\t'no',\ndiff --git a/stgit/git.py b/stgit/git.py\nindex 46ba5c8..458eb97 100644\n--- a/stgit/git.py\n+++ b/stgit/git.py\n@@ -817,7 +817,24 @@ def fetch(repository = 'origin', refspec = None):\n     if refspec:\n         args.append(refspec)\n \n-    command = config.get('stgit.pullcmd')\n+    command = config.get('branch.%s.stgit.fetchcmd' % get_head_file()) or \\\n+              config.get('stgit.fetchcmd')\n+    if __run(command, args) != 0:\n+        raise GitException, 'Failed \"%s %s\"' % (command, repository)\n+\n+def pull(repository = 'origin', refspec = None):\n+    \"\"\"Fetches changes from the remote repository, using 'git-pull'\n+    by default.\n+    \"\"\"\n+    # we update the HEAD\n+    __clear_head_cache()\n+\n+    args = [repository]\n+    if refspec:\n+        args.append(refspec)\n+\n+    command = config.get('branch.%s.stgit.pullcmd' % get_head_file()) or \\\n+              config.get('stgit.pullcmd')\n     if __run(command, args) != 0:\n         raise GitException, 'Failed \"%s %s\"' % (command, repository)\n \ndiff --git a/t/t2100-pull-policy-fetch.sh b/t/t2100-pull-policy-fetch.sh\nnew file mode 100755\nindex 0000000..e1398a3\n--- /dev/null\n+++ b/t/t2100-pull-policy-fetch.sh\n@@ -0,0 +1,72 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2007 Yann Dirson\n+#\n+\n+test_description='Excercise pull-policy \"fetch-rebase\".'\n+\n+. ./test-lib.sh\n+\n+# don't need this repo, but better not drop it, see t1100\n+#rm -rf .git\n+\n+# Need a repo to clone\n+test_create_repo upstream\n+\n+test_expect_success \\\n+    'Setup upstream repo, clone it, and add patches to the clone' \\\n+    '\n+    (cd upstream && stg init) &&\n+    stg clone upstream clone &&\n+    (cd clone &&\n+     git repo-config branch.master.stgit.pull-policy fetch-rebase &&\n+     git repo-config --list &&\n+     stg new c1 -m c1 &&\n+     echo a > file && stg add file && stg refresh\n+    )\n+    '\n+\n+test_expect_success \\\n+    'Add non-rewinding commit upstream and pull it from clone' \\\n+    '\n+    (cd upstream && stg new u1 -m u1 &&\n+     echo a > file2 && stg add file2 && stg refresh) &&\n+    (cd clone && stg pull) &&\n+    test -e clone/file2\n+    '\n+\n+# note: with pre-1.5 Git the clone is not automatically recorded\n+# as rewinding, and thus heads/origin is not moved, but the stack\n+# is still correctly rebased\n+test_expect_success \\\n+    'Rewind/rewrite upstream commit and pull it from clone' \\\n+    '\n+    (cd upstream && echo b >> file2 && stg refresh) &&\n+    (cd clone && stg pull) &&\n+    test `wc -l <clone/file2` = 2\n+    '\n+\n+# this one ensures the guard against commits does not unduly trigger\n+test_expect_success \\\n+    'Rewind/rewrite upstream commit and fetch it from clone before pulling' \\\n+    '\n+    (cd upstream && echo c >> file2 && stg refresh) &&\n+    (cd clone && git fetch && stg pull) &&\n+    test `wc -l <clone/file2` = 3\n+    '\n+\n+# this one exercises the guard against commits\n+# (use a new file to avoid mistaking a conflict for a success)\n+test_expect_success \\\n+    'New upstream commit and commit a patch in clone' \\\n+    '\n+    (cd upstream && stg new u2 -m u2 &&\n+     echo a > file3 && stg add file3 && stg refresh) &&\n+    (cd clone && stg commit && stg new c2 -m c2 &&\n+     echo a >> file && stg refresh)\n+    '\n+test_expect_failure \\\n+    'Try to  and commit a patch in clone' \\\n+    '(cd clone && stg pull)'\n+\n+test_done\n"}]}