Merge ~apw/+git/kteam-tools:cranky/checkout--add-roles-for-prepare-and-apply into ~canonical-kernel/+git/kteam-tools:master

Proposed by Andy Whitcroft
Status: Work in progress
Proposed branch: ~apw/+git/kteam-tools:cranky/checkout--add-roles-for-prepare-and-apply
Merge into: ~canonical-kernel/+git/kteam-tools:master
Diff against target: 250 lines (+104/-31)
4 files modified
cranky/cmds.d/checkout (+21/-5)
cranky/crl/git.py (+11/-11)
cranky/crl/handle.py (+26/-4)
cranky/docs/cranking-the-kernel.md (+46/-11)
Reviewer Review Type Date Requested Status
Canonical Kernel Team Pending
Canonical Kernel Team Pending
Review via email: mp+400701@code.launchpad.net

Commit message

This patch stack adds support to `cranky checkout` for separation of
roles for kernel preparation and patch application. This adds new
command line options to checkout: --prepare-kernels and --apply-patches.
Defaulting to --prepare-kernels for compatibility with current
semantics.

This patch set changes the local branch namespace for cranky generated
branches to `cranky-{prepare,apply}/<kernel-suffix>`. This is done
to disambiguate clearly which function the local branch fills. It also
simplifies branch destination selection for push.

This patch set changes a number of things:

1) it adds the concept of local_branch to our Handle objects allowing us
to reuse the existing overlap handling used for remotes,
2) it adds the concept of local_branch to our GitHandle object allowing
us to feed roll and source information into the branch selection,
3) adds some extra summary information indicating where the branch
came from (and should push to), and
4) automatically keeps the git concept of upstream branch updated.

This last feature in concert with a simple addition to the users basic
git config allows us to simply `git push` on any `cranky-*/*` branch and
have it go back to whence it came. It is hoped this will simplify or
eliminate the need for a `cranky push`.

To post a comment you must log in.
8d0c7f2... by Andy Whitcroft

cranky: docs/cranking-the-kernel -- add patch application instructions

Add patch application instructions. As we now need slightly more git
configuration also add a new section on that which lists all the main
configuration you should need to change.

Signed-off-by: Andy Whitcroft <email address hidden>

08c1545... by Andy Whitcroft

cranky: crl/git -- default role to prepare when not specified

Signed-off-by: Andy Whitcroft <email address hidden>

Revision history for this message
Marcelo Cerri (mhcerri) :
Revision history for this message
Marcelo Cerri (mhcerri) :
Revision history for this message
Marcelo Cerri (mhcerri) :

Unmerged commits

08c1545... by Andy Whitcroft

cranky: crl/git -- default role to prepare when not specified

Signed-off-by: Andy Whitcroft <email address hidden>

8d0c7f2... by Andy Whitcroft

cranky: docs/cranking-the-kernel -- add patch application instructions

Add patch application instructions. As we now need slightly more git
configuration also add a new section on that which lists all the main
configuration you should need to change.

Signed-off-by: Andy Whitcroft <email address hidden>

feeb2e1... by Andy Whitcroft

cranky: crl/git -- ensure that the git upstream pointer is correct

When we clone/checkout/reset a branch to update it ensure we set
the upstream pointer to the upstream remote/branch so that we can
push the branch back to whence it came.

With this in place, we can add the following confiuration to our
.gitconfig file:

    [includeIf "onbranch:cranky-*/*"]
        path=~/.gitconfig--cranky

Adding this as ~/.gitconfig--cranky:

    [push]
        default=upstream

Then a simple `git push` on a checked out `cranky-prepare/*` or
`cranky-apply/*` branch will push to the branch from which `cranky
checkout` pulled it.

Signed-off-by: Andy Whitcroft <email address hidden>

c11e5b5... by Andy Whitcroft

cranky: checkout -- add remote and branch to summary

We report a lot of information about the local branch on which we are
checking out. Include the remote name and remote branch in the summary
data.

Signed-off-by: Andy Whitcroft <email address hidden>

72665b2... by Andy Whitcroft

cranky: checkout -- add prepare and apply roles

Add --prepare-kernel (alias --prepare) and --apply-patches (alias
--apply) options to indicate the role for which you want to checkout.
Use this to form the branch name on which we checkout the destination so
that we can better track where the branch should go when pushed.

Signed-off-by: Andy Whitcroft <email address hidden>

79b0fa0... by Andy Whitcroft

cranky: crl/git -- get_cranky_branch_name add role information

In preparation for splitting the crank and apply roles in `cranky
checkout` start taking the role when forming the local branch names.

Signed-off-by: Andy Whitcroft <email address hidden>

4516239... by Andy Whitcroft

cranky: crl/git -- add local_branch and use for cranky

Add local_branch property which consumes the Handle's local_branch
information and forms a `cranky/` branch from it.

Signed-off-by: Andy Whitcroft <email address hidden>

c47c0aa... by Andy Whitcroft

cranky: crl/handle -- HandleTree add local_branch

Work out the local branch name for a branch from the associated package.
Use the same mixing detection logic we use for the remote name to
prevent collisions in the cranky/ branch namespace.

Signed-off-by: Andy Whitcroft <email address hidden>

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/cranky/cmds.d/checkout b/cranky/cmds.d/checkout
2index 301c5a6..6dfbfd7 100755
3--- a/cranky/cmds.d/checkout
4+++ b/cranky/cmds.d/checkout
5@@ -14,7 +14,7 @@ from crl.handle import HandleError
6 from ktl.log import cerror, cnotice
7
8
9-def checkout_repos(handle, reference=None, dissociate=False):
10+def checkout_repos(handle, reference=None, dissociate=False, role=None):
11 """
12 Clone the repos that make up the set of kernel packages
13 """
14@@ -47,19 +47,18 @@ def checkout_repos(handle, reference=None, dissociate=False):
15 pkg = gh.package
16 remote = gh.remote
17 rmt_branch = gh.remote_branch
18- branch = gh.get_cranky_branch_name()
19+ branch = gh.get_cranky_branch_name(role)
20
21 # Add info for the summary
22 summary.append({"name": pkg.name, "dir": gh.directory, "remote": remote,
23- "branch": branch})
24+ "branch": branch, "remote-branch": rmt_branch})
25
26 gh.checkout(remote, rmt_branch, branch)
27
28 # Print the summary
29 cnotice("Summary:")
30 for s in summary:
31- cnotice(" Repo '{}' in directory '{}' (branch '{}')".format(
32- s["name"], s["dir"], s["branch"]))
33+ cnotice(" Repo '{name}' in directory '{dir}' (branch '{branch}' remote '{remote} {remote-branch})".format(**s))
34
35
36 def expanduser(path):
37@@ -143,6 +142,16 @@ Borrow the objects from the referenced local repository only to reduce network
38 traffic. This is a git clone option, check 'git help clone' for more details.
39 """
40
41+ help_apply = """
42+Check out the application branch for this repository.
43+"""
44+
45+ help_prepare = """
46+Check out the preparation branch for this repository.
47+"""
48+
49+ default_branch = config_cmd.get('default-branch', 'prepare')
50+
51 formatter = argparse.RawDescriptionHelpFormatter
52 parser = argparse.ArgumentParser(description=desc,
53 formatter_class=formatter,
54@@ -155,6 +164,13 @@ traffic. This is a git clone option, check 'git help clone' for more details.
55 parser.add_argument("-d", "--dissociate", action="store_true",
56 default=config_cmd.get('dissociate', False),
57 help=help_dissociate)
58+ parser.set_defaults(role=default_branch)
59+ parser.add_argument("--apply-patches", "--apply", dest="role", action="store_const",
60+ const="apply",
61+ help=help_apply)
62+ parser.add_argument("--prepare-kernel", "--prepare", dest="role", action="store_const",
63+ const="prepare",
64+ help=help_prepare)
65
66 try:
67 checkout_repos(**vars(parser.parse_args()))
68diff --git a/cranky/crl/git.py b/cranky/crl/git.py
69index 63d55bc..4c9dd8f 100644
70--- a/cranky/crl/git.py
71+++ b/cranky/crl/git.py
72@@ -54,6 +54,10 @@ class GitHandle():
73 return self.__ht.remote
74
75 @property
76+ def local_branch(self):
77+ return self.__ht.local_branch
78+
79+ @property
80 def remote_branch(self):
81 pkg = self.__ht.package
82
83@@ -96,20 +100,11 @@ class GitHandle():
84
85 return sha1
86
87- def get_cranky_branch_name(self):
88+ def get_cranky_branch_name(self, role='prepare'):
89 '''
90 Return the local branch name which is used by cranky.
91 '''
92- pkg = self.package
93- remote = self.remote
94-
95- # Cranky branch is the real branch name if we are checking out against 'origin',
96- # the derivative's source name otherwise.
97- branch_suffix = pkg.repo.branch if pkg.repo.branch else 'master'
98- if remote != 'origin':
99- branch_suffix = pkg.source.name.replace('linux-', '')
100-
101- return 'cranky/' + branch_suffix
102+ return 'cranky-' + role + '/' + self.local_branch
103
104 def get_url(self):
105 '''
106@@ -167,6 +162,11 @@ class GitHandle():
107 if result.returncode != 0:
108 raise GitError("unable to reset to new tip tip rc={}".format(result.returncode))
109
110+ # Ensure the upstream branch reference points to where we are resrtting to.
111+ result = run(["git", "branch", "-q", "--set-upstream-to=" + rmt_ref], cwd=self.directory)
112+ if result.returncode != 0:
113+ raise GitError("unable to set upstream to remote branch rc={}".format(result.returncode))
114+
115 # Validate whether the right branch is checked out.
116 validate_hdl = Handle().lookup_tree(self.directory)
117 if self.package != validate_hdl.package:
118diff --git a/cranky/crl/handle.py b/cranky/crl/handle.py
119index 9c261f3..f50fd85 100755
120--- a/cranky/crl/handle.py
121+++ b/cranky/crl/handle.py
122@@ -153,8 +153,7 @@ class HandleTree(HandleCore):
123
124 self.directory = directory
125
126- @property
127- def remote(self):
128+ def _evaluate_cross(self):
129 cross_series = False
130 cross_source = False
131 cross_type = False
132@@ -187,9 +186,32 @@ class HandleTree(HandleCore):
133 bits.append(primary_package.source.name.replace('linux-', ''))
134 if cross_type and primary_package.type:
135 bits.append(primary_package.type)
136-
137 remote = '-'.join(bits)
138- return remote if remote != '' else 'origin'
139+ if remote == '':
140+ remote = 'origin'
141+
142+ bits = []
143+ if cross_series:
144+ bits.append(self.package.series.codename)
145+ if cross_source and self.package.source.name != 'linux':
146+ bits.append(self.package.source.name.replace('linux-', ''))
147+ if cross_type and self.package.type:
148+ bits.append(self.package.type)
149+ branch = '-'.join(bits)
150+ if branch == '':
151+ branch = 'linux'
152+
153+ return remote, branch
154+
155+ @property
156+ def remote(self):
157+ remote, branch = self._evaluate_cross()
158+ return remote
159+
160+ @property
161+ def local_branch(self):
162+ remote, branch = self._evaluate_cross()
163+ return branch
164
165
166 class HandleSet(HandleCore):
167diff --git a/cranky/docs/cranking-the-kernel.md b/cranky/docs/cranking-the-kernel.md
168index a638619..17840b5 100644
169--- a/cranky/docs/cranking-the-kernel.md
170+++ b/cranky/docs/cranking-the-kernel.md
171@@ -63,9 +63,40 @@ cranky chroot create-base xenial:linux
172 cranky chroot create-session configs xenial:linux
173 ```
174
175+### Setup git configuration
176+
177+You should teach git your real name and email address via your
178+`~/.gitconfig`:
179+
180+```
181+git config --global user.name 'Your Name'
182+git config --global user.email 'you@canonical.com'
183+```
184+
185+In order for a simple `git push` to work on your `cranky` branches
186+we need to teach `git` about those branches. The easiest way to do
187+this is to run the following to add appropriate configuration to your
188+`~/.gitconfig`:
189+
190+```
191+git config --file ~/.gitconfig--cranky push.default upstream
192+git config --global 'includeIf.onbranch:cranky-*/*.path' '~/.gitconfig--cranky'
193+```
194+
195+**Note**: Private kernel repositories (including security) will get
196+checked out using a `git+ssh://` URL. If your local username and your
197+Launchpad ID are not the same, then the following additional mapping
198+is needed in your `~/.gitconfig` file:
199+
200+```
201+git config --global \
202+ 'url.git+ssh://<your-launchpad-id>@git.launchpad.net/.insteadof' \
203+ 'git+ssh://git.launchpad.net/'
204+```
205+
206 ## Build
207
208-### Clone and checkout the kernel repository - `cranky checkout`
209+### Clone and checkout the kernel repository (to prepare) - `cranky checkout`
210 <!--cheatsheet-->
211 ```
212 cranky checkout RELEASE:KERNEL
213@@ -80,16 +111,6 @@ cd canonical/kernel/ubuntu
214 cranky checkout xenial:linux-oracle
215 ```
216
217-**Note**: Private kernel repositories (including security) will get
218-checked out using a `git+ssh://` URL. If your local username and your
219-Launchpad ID are not the same, then the following mapping is needed
220-in your `~/.gitconfig` file:
221-
222-```
223-[url "git+ssh://<your-launchpad-id>@git.launchpad.net/"]
224- insteadof = "git+ssh://git.launchpad.net/"
225-```
226-
227 ### dkms package update stage - `update-version-dkms`
228 <!--cheatsheet-->
229 ```
230@@ -516,6 +537,20 @@ $ cd linux-oracle
231 $ cranky build-sources --build-opts "main:-v4.15.0-1021.23~16.04.1" --build-opts "meta:-v4.15.0.1021.15" --build-opts "signed:-v4.15.0-1021.23~16.04.1"
232 ```
233
234+## Patching
235+
236+### Clone and checkout the kernel repository (to apply patches) - `cranky checkout --apply-patches`
237+<!--cheatsheet-->
238+```
239+cranky checkout --apply-patches RELEASE:KERNEL
240+```
241+<!--/cheatsheet-->
242+
243+Use `cranky checkout --apply-patches` to get the kernel that you want to apply patches to.
244+
245+Apply patches in the normal way with `git am -s`. Once complete you should be able
246+to push the updated branch to its original branch using a simple `git push`.
247+
248 ## Review
249
250 ### Reviewing - `cranky review`

Subscribers

People subscribed via source and target branches