Merge lp:~mattyw/codetree/git-branch into lp:codetree

Proposed by Matthew Williams
Status: Merged
Merged at revision: 86
Proposed branch: lp:~mattyw/codetree/git-branch
Merge into: lp:codetree
Diff against target: 135 lines (+75/-5)
3 files modified
README.md (+4/-0)
codetree/handlers/git.py (+10/-4)
tests/test_git_handler.py (+61/-1)
To merge this branch: bzr merge lp:~mattyw/codetree/git-branch
Reviewer Review Type Date Requested Status
Tim Kuhlman (community) Approve
Review via email: mp+316830@code.launchpad.net

Commit message

Added support for specifying a branch=branch-name option when cloning. This is distinct from the revno option which clones master then checkouts the relevent branch. The branch option will only clone the specified branch

Description of the change

Added support for specifying a branch=branch-name option when cloning. This is distinct from the revno option which clones master then checkouts the relevent branch. The branch option will only clone the specified branch

To post a comment you must log in.
Revision history for this message
Tim Kuhlman (timkuhlman) wrote :

I'm assuming the use case is to minimize the size of what gets downloaded by codetree.

The distinction between clone master/checkout revno and clone a specific branch is only important when both doing a branch checkout and specifying a depth, without depth it is equivalent to just using revno. The '--single-branch' argument should be added when '-b' is added to achieve the smaller download without having to specify depth.

Please update README.md documenting the new options.

review: Needs Fixing
Revision history for this message
Matthew Williams (mattyw) wrote :

> I'm assuming the use case is to minimize the size of what gets downloaded by
> codetree.
>
> The distinction between clone master/checkout revno and clone a specific
> branch is only important when both doing a branch checkout and specifying a
> depth, without depth it is equivalent to just using revno. The '--single-
> branch' argument should be added when '-b' is added to achieve the smaller
> download without having to specify depth.
>
> Please update README.md documenting the new options.

Hi Tim,

You're right about wanting to minimize what gets downloaded. Just to make sure I understand your suggestion. If -b is specified but not --depth you'd expect the --single-branch option to be set. Is that what you mean?

Revision history for this message
Stuart Bishop (stub) wrote :

(confusion here might be that the revno option also accepts tags and branch names, because git).

Revision history for this message
Tim Kuhlman (timkuhlman) wrote :

Matthew, yes if you specify -b on git clone I believe it still download the entire repository and then does a switch to that branch, it is only if you specify both -b and either depth or --single-branch that it will download just the one branch.

lp:~mattyw/codetree/git-branch updated
87. By Matthew Williams

git: Added --single-branch if -b option is specified

88. By Matthew Williams

git.py: Added comment to test

Revision history for this message
Tim Kuhlman (timkuhlman) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'README.md'
2--- README.md 2016-12-01 23:11:15 +0000
3+++ README.md 2017-02-10 17:27:57 +0000
4@@ -64,6 +64,10 @@
5 revno: Checkout a specific revision. For Git branches this is any git branch, tag or ref understood by git checkout, defaulting to master. The charm store does not support revno as the revision is specified as part of the url.
6 overwrite: If the destination directory already exists, just overwrite it. Otherwise it is an error.
7
8+**Git Only**
9+depth: Use "git clone --depth n" to create a shallow clone only up to n revisions.
10+branch: Use "git clone -b <branch> --single-branch" to clone a single branch rather than clone all then checkout.
11+
12 **BZR Only**
13 lightweight: Use "bzr checkout --lightweight" rather than "bzr branch". Only supported for Bazaar branches.
14
15
16=== modified file 'codetree/handlers/git.py'
17--- codetree/handlers/git.py 2017-01-17 11:35:12 +0000
18+++ codetree/handlers/git.py 2017-02-10 17:27:57 +0000
19@@ -9,7 +9,7 @@
20 )
21
22 from .basic import HandlerResult, SourceHandler
23-from .exceptions import NotABranch, NotSameBranch
24+from .exceptions import NotABranch, NotSameBranch, InvalidOption
25 from .utils import log_failure
26
27
28@@ -65,11 +65,17 @@
29 def get(self, dest, options):
30 result = HandlerResult(False, source=self.source_raw, dest=dest, options=options)
31 ref = options.get('revno')
32+ depth = options.get('depth')
33+ branch = options.get('branch')
34+ if branch and ref:
35+ raise InvalidOption("revno and branch")
36
37 clone_command = ['git', 'clone', self.source, dest]
38- if options.get("depth"):
39- depth = int(options.get("depth"))
40- clone_command.extend(["--depth", str(depth)])
41+ if depth:
42+ d = int(depth)
43+ clone_command.extend(["--depth", str(d)])
44+ if branch:
45+ clone_command.extend(["--single-branch", "-b", str(options.get("branch"))])
46 if os.path.exists(dest):
47 if options.get("overwrite"):
48 shutil.rmtree(dest)
49
50=== modified file 'tests/test_git_handler.py'
51--- tests/test_git_handler.py 2017-01-17 11:35:12 +0000
52+++ tests/test_git_handler.py 2017-02-10 17:27:57 +0000
53@@ -8,7 +8,8 @@
54 from codetree.handlers import (
55 GitSourceHandler,
56 NotABranch,
57- NotSameBranch
58+ NotSameBranch,
59+ InvalidOption
60 )
61
62
63@@ -25,6 +26,15 @@
64 with open(os.path.join(self._gitdir, 'file'), 'w') as f:
65 f.write('branch B')
66 subprocess.check_call(('git', '-C', self._gitdir, 'commit', '-q', '-a', '-m', 'branch B'))
67+
68+ # Do an orphan checkout here to test the behaviour of the --single-branch behaviour.
69+ subprocess.check_call(('git', '-C', self._gitdir, 'checkout', '--orphan', 'branch-single'))
70+ subprocess.check_call(('git', '-C', self._gitdir, 'rm', '-rf', ''))
71+ with open(os.path.join(self._gitdir, 'file'), 'w') as f:
72+ f.write('single branch')
73+ subprocess.check_call(('git', '-C', self._gitdir, 'add', 'file'))
74+ subprocess.check_call(('git', '-C', self._gitdir, 'commit', '-q', '-m', 'tag single branch'))
75+
76 subprocess.check_call(('git', '-C', self._gitdir, 'checkout', '-q', 'master'))
77 with open(os.path.join(self._gitdir, 'file'), 'w') as f:
78 f.write('revision')
79@@ -130,6 +140,56 @@
80 finally:
81 shutil.rmtree(d)
82
83+ def test_get_specific_branch(self):
84+ gh = GitSourceHandler("git://localhost/.git")
85+ d = mkdtemp('', 'git-handler')
86+ wd = os.path.join(d, 'test')
87+ try:
88+ gh.get(wd, {'branch': 'branch-B'})
89+ with open(os.path.join(wd, 'file')) as f:
90+ c = f.read()
91+ self.assertEqual('branch B', c)
92+ finally:
93+ shutil.rmtree(d)
94+
95+ def test_get_branch_and_revno(self):
96+ gh = GitSourceHandler("git://localhost/.git")
97+ d = mkdtemp('', 'git-handler')
98+ wd = os.path.join(d, 'test')
99+ try:
100+ with self.assertRaises(InvalidOption):
101+ gh.get(wd, {'revno': self._revision, 'branch': 'branch-B'})
102+ finally:
103+ shutil.rmtree(d)
104+
105+ def test_get_branch_with_depth(self):
106+ gh = GitSourceHandler("git://localhost/.git")
107+ d = mkdtemp('', 'git-handler')
108+ wd = os.path.join(d, 'test')
109+ try:
110+ gh.get(wd, {'branch': 'branch-B', 'depth': '1'})
111+ with open(os.path.join(wd, 'file')) as f:
112+ c = f.read()
113+ self.assertEqual('branch B', c)
114+ rev_count = subprocess.check_output(gh._git_cmd(wd, 'rev-list', '--count', '--all'), universal_newlines=True)
115+ self.assertEqual('1', rev_count.strip())
116+ finally:
117+ shutil.rmtree(d)
118+
119+ def test_get_single_branch(self):
120+ gh = GitSourceHandler("git://localhost/.git")
121+ d = mkdtemp('', 'git-handler')
122+ wd = os.path.join(d, 'test')
123+ try:
124+ gh.get(wd, {'branch': 'branch-single'})
125+ with open(os.path.join(wd, 'file')) as f:
126+ c = f.read()
127+ self.assertEqual('single branch', c)
128+ result = subprocess.call(gh._git_cmd(wd, 'checkout', 'branch-B'))
129+ self.assertEqual(1, result)
130+ finally:
131+ shutil.rmtree(d)
132+
133 def test_directory_exists(self):
134 gh = GitSourceHandler("git://localhost/.git")
135 d = mkdtemp('', 'git-handler')

Subscribers

People subscribed via source and target branches