-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathREADME
250 lines (187 loc) · 8.67 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
TopGit -- A Different Patch Queue Manager
=========================================
Overview
--------
TopGit manages one or more "patch queue"s (aka "patch set"s) using
Git.
Whereas a utility such as `quilt` maintains each individual patch
as a "diff" file on disk, TopGit (the `tg` command) maintains each
individual patch as _two_ branches in Git -- the patch's "branch"
and the patch's "base branch". The patch itself is simply the
"diff" from the patch's "base branch" to the patch's "branch".
Whereas a utilty such as `quilt` maintains the list of active patch
"diff" files and the correct order to apply them in a file (the
`series` file), TopGit maintains this information in a `.topdeps`
file that is part of each patch's "branch".
TopGit maintains any desired "documentation" (aka the patch header)
in a `.topmsg` file that is also part of each patch's "branch" and
prepends it when generating a patch "diff".
Simplistic Quilt vs. TopGit Example
-----------------------------------
Consider the following files:
frabjous.tar.gz # tarball of "frabjous" sources
0001-brillig.diff # first patch to apply
0002-gimble.diff # second patch to apply
With Quilt they might be used like so:
$ tar -xzf frabjous.tar.gz
$ cd frabjous
$ quilt import ../0001-brillig.diff && quilt push
$ quilt import ../0002-gimble.diff && quilt push
$ quilt applied
patches/0001-brillig.diff
patches/0002-gimble.diff
With TopGit they might be used like so:
$ tar -xzf frabjous.tar.gz
$ cd frabjous
$ git -c init.defaultBranch=master init && git add -A
$ git -c user.name=- -c user.email=- commit -qm frabjous
$ git checkout -b patches
$ git -c user.name=- -c user.email=- am ../0001-brillig.diff
$ git -c user.name=- -c user.email=- am ../0002-gimble.diff
$ git checkout master
$ git config topgit.top-bases heads # not the default...yet!
$ tg -c user.name=- -c user.email=- import ..patches
$ git branch
master
patches
t/brillig
* t/gimble
{top-bases}/t/brillig
{top-bases}/t/gimble
$ tg summary
t/brillig [PATCH] brillig
> t/gimble [PATCH] gimble
$ tg summary --rdeps --heads
t/gimble
t/brillig
master
Whereas with Quilt, the "0001-brillig.diff" patch is maintained as
the original patch file (in `patches/0001-brillig.diff`), with
TopGit, the "0001-brillig.diff" patch becomes _two_ Git branches,
`{top-bases}/t/brillig` which represents the sources before the
"0001-brillig.diff" patch has been applied and `t/brillig` which
represents the sources after the "0001-brillig.diff" patch has been
applied.
The original "0001-brillig.diff" patch can be re-generated with this
TopGit command:
$ tg patch t/brillig
And is roughly equivalent to the diff from the `{top-bases}/t/brillig`
branch to the `t/brillig` branch. (It's the diff excluding the two
TopGit metadata files with the patch header prepended to the result.)
To work on the "brillig" patch, one simply does a checkout of the
`t/brillig` branch and makes and commits changes as normal using
regular Git commands. After the changes have been made, the "gimble"
patch may need updating if any of the changes made to the "brillig"
patch modified the same files affected by the "gimble" patch. That
can be accomplished with this command:
$ tg update --all
Finally, when a new set of ".diff" patch files needs to be generated,
these commands can be used:
$ git checkout t/gimble
$ tg export --quilt --strip --numbered patchdir
$ ls -1 patchdir
0001-brillig.diff
0002-gimble.diff
series
TopGit Advantages
-----------------
### Patch Dependency Topology
Whereas the `series` file in Quilt is (obviously) limited to a
"linear" topology, TopGit's `.topdeps` file is not.
For example, consider that you have three patches:
1. add "feature A"
2. add "feature B"
3. add "feature C" that requires both feature A and feature B
If "feature A" and "feature B" are completely independent features,
then the order that the "feature A" and "feature B" patches are
applied does not matter as long as they are both applied before the
"feature C" patch.
TopGit can represent this by listing both the "feature A" and
"feature B" patches in the `.topdeps` file for the "feature C"
patch.
### Patch Change History
Whereas with Quilt there is no history of changes (aka edits) to a
patch (unless explicit backups are made along the way), all changes
to a patch in TopGit are made via regular Git commands.
This means all the standard Git introspection commands (e.g. "log",
"diff", "bisect", "blame", etc.) are available to view the history
of an individual patch.
### Patch Updating
With Quilt when the "upstream" sources are updated (or even an early
patch in the series is updated) in such a way as to cause a patch
to no longer apply cleanly, the patch must be fixed by hand.
With TopGit, the full Git merge machinery is used to merge the
"upstream" changes (or changes to an earlier patch) into the patches
in dependency topological order. This can often avoid patch
conflicts.
In the case where a patch must be fixed by hand (yes, this still
can happen in TopGit), the Git `rerere` (reuse recorded resolution)
mechanism can be used to record the hand-crafted fix and later
automatically reuse that fix when needed.
### Patch Identification
When there are a very large number of patches in a patch set, it
may be difficult to remember (especially if you're not the original
author) which individual patch of a "patch set" contains a particular
change.
After using the various Git introspection commands (e.g. "log",
"diff", "bisect", "blame", etc.) to locate a commit containing a
particular change, the TopGit `tg contains` command can be used to
identify the individual patch of a "patch set" that logically
contains that commit.
In other words, `tg contains` identifies which TopGit branch would
produce a patch "diff" file that makes the change introduced by the
given commit.
### Collaboration
Because TopGit stores all information directly in Git, all of Git's
normal push/pull/remote functionality can be used to collaborate
on and/or share TopGit "patch set"s with others. The `tg push`
command facilitates pushing all branches in one or more TopGit
"patch set"s at once.
TopGit Features
---------------
### Multiple Patch Sets
With Quilt it is possible to use different `series` files to combine
patch "diff" files into different arrangements (e.g. for different
machine architectures or development branches).
TopGit also allows multiple "patch set"s to exist at the same time
where a single "patch" may be used by more than one "patch set".
### Patch Set History
As an alternative to maintaining two or more different versions of
the same patch (e.g. for different development branches) under
different names such as, for example, "patch1-oldstable", "patch1-stable"
and "patch1-unstable", it's possible to use a TopGit tag to record
the state of a "patch set" (via the `tg tag` command) and then later
go back to that state (via the `tg shell` command) to, for example,
produce an updated patch set for an older software version and
record that new state of the older software version "patch set"
without disturbing the current version of the "patch set".
The advantage of using this mechanism is that the branch names for
the individual patches always remain the same no matter how many
different versions are being kept.
### Import and Export
TopGit can import and export "patch set"s to other formats. This
includes the one "diff" file per patch and one "commit" per patch
formats.
This makes it easy to produce a set of "diff" patch files on demand
for external (e.g. non-Git) use for a "patch set".
TopGit Downsides
----------------
Forget about using `git rebase` on a TopGit branch (either a patch's
"branch" or its "base branch"). With the exception being commits
that have not yet been merged into any other patch's "branch" or
"base branch". (TopGit does, however, have its own `tgstash` that
provides a kind of "undo" after unfortunate update accidents.)
The merge history for a "patch set" can become rather complex as a
"patch set" is maintained over time (via the `tg update` command)
since nothing is ever thrown away.
TopGit has a learning curve and those unfamiliar with Git will need
to become comfortable with Git too.
Additional Information
----------------------
[Full documentation][1] is available including a [fully formatted
version of the manual][2] (created from `README_DOCS.rst` which
incorporates a few [examples][3]) and the [TopGit changelog][4].
[1]: https://mackyle.github.io/topgit
[2]: https://mackyle.github.io/topgit/topgit.html
[3]: https://mackyle.github.io/topgit/topgit.html#synopsis
[4]: https://mackyle.github.io/topgit/changelog.html