I've been making myself more familiar with git lately and I'm curious what
habits others have adopted. (I know there are a few documents in circulation
that deal with using git to work on the kernel but I don't think this has
been specifically covered).
My question is: If you're working on multiple things at once, do you tend to
clone the entire repository repeatedly into a series of separate working
directories and do your work there, then pull that work (possibly comprising
a series of "temporary" commits) back into a separate local master
respository with --squash, either into "master" or into a branch containing
the new feature?
Or perhaps you create a temporary topical branch for each thing you are
working on, and commit arbitrary changes then checkout another branch when
you need to change gears, finally --squashing the intermediate commits when a
particular piece of work is done?
I'm using git to manage my project and I'm trying to determine the most
optimal workflow I can. I figure that I'm going to have an "official" master
repository for the project, and I want to keep the revision history clean in
that repository (ie, no messy intermediate commits that don't compile or only
implement a feature half way).
On older projects I was using a certalized revision control system like
*cough* Subversion *cough* and I'd create separate branches which I'd check
out into their own working trees.
It seems to me that having multiple working trees (effectively, cloning
the "master" repository every time I need to make anything but a trivial
change) would be most effective under git as well as it doesn't require
creating messy, intermediate commits in the first place (but allows for them
if they are used). But I wonder how that approach would scale with a project
whose git repo weighed hundreds of megs or more. (With a centralized rcs, of
course, you don't have to lug around a copy of the whole project history in
each working tree.)
Insight appreciated, and I apologize if I've failed to RTFM somewhere.
Thanks,
Chase
From: Jan Engelhardt <hidden> Date: 2008-02-23 01:37:25
On Feb 22 2008 18:37, Chase Venters wrote:
I've been making myself more familiar with git lately and I'm curious what
habits others have adopted. (I know there are a few documents in circulation
that deal with using git to work on the kernel but I don't think this has
been specifically covered).
My question is: If you're working on multiple things at once,
Impossible; Humans only have one core with only seven registers --
according to CodingStyle chapter 6 paragraph 4.
do you tend to clone the entire repository repeatedly into a series
of separate working directories
Too time consuming on consumer drives with projects the size of Linux.
and do your work there, then pull
that work (possibly comprising a series of "temporary" commits) back
into a separate local master respository with --squash, either into
"master" or into a branch containing the new feature?
No, just commit the current unfinished work to a new branch and deal
with it later (cherry-pick, rebase, reset --soft, commit --amend -i,
you name it). Or if all else fails, use git-stash.
You do not have to push these temporary branches at all, so it is
much nicer than svn. (Once all the work is done and cleanly in
master, you can kill off all branches without having a record
of their previous existence.)
Or perhaps you create a temporary topical branch for each thing you
are working on, and commit arbitrary changes then checkout another
branch when you need to change gears, finally --squashing the
intermediate commits when a particular piece of work is done?
if I don't collect arbitrary changes, I don't need squashing
(see reset --soft/amend above)
From: Daniel Barkalow <hidden> Date: 2008-02-23 04:11:02
On Fri, 22 Feb 2008, Chase Venters wrote:
I've been making myself more familiar with git lately and I'm curious what
habits others have adopted. (I know there are a few documents in circulation
that deal with using git to work on the kernel but I don't think this has
been specifically covered).
My question is: If you're working on multiple things at once, do you tend to
clone the entire repository repeatedly into a series of separate working
directories and do your work there, then pull that work (possibly comprising
a series of "temporary" commits) back into a separate local master
respository with --squash, either into "master" or into a branch containing
the new feature?
Or perhaps you create a temporary topical branch for each thing you are
working on, and commit arbitrary changes then checkout another branch when
you need to change gears, finally --squashing the intermediate commits when a
particular piece of work is done?
I find that the sequence of changes I make is pretty much unrelated to the
sequence of changes that end up in the project's history, because my
changes as I make them involve writing a lot of stubs (so I can build) and
then filling them out. It's beneficial to have version control on this so
that, if I screw up filling out a stub, I can get back to where I was.
Having made a complete series, I then generate a new series of commits,
each of which does one thing, without any bugs that I've resolved, such
that the net result is the end of the messy history, except with any
debugging or useless stuff skipped. It's this series that gets merged into
the project history, and I discard the other history.
The real trick is that the early patches in a lot of series often refactor
existing code in ways that are generally good and necessary for your
eventual outcome, but which you'd never think of until you've written more
of the series. Generating a new commit sequence is necessary to end up
with a history where it looks from the start like you know where you're
going and have everything done that needs to be done when you get to the
point of needing it. Furthermore, you want to be able to test these
commits in isolation, without the distraction of the changes that actually
prompted them, which means that you want to have your working tree is a
state that you never actually had it in as you were developing the end
result.
This means that you'll usually want to rewrite commits for any series that
isn't a single obvious patch, so it's not a big deal to commit any time
you want to work on some different branch.
-Daniel
*This .sig left intentionally blank*
From: Rene Herman <hidden> Date: 2008-02-23 04:37:41
On 23-02-08 01:37, Chase Venters wrote:
Or perhaps you create a temporary topical branch for each thing you are
working on, and commit arbitrary changes then checkout another branch
when you need to change gears, finally --squashing the intermediate
commits when a particular piece of work is done?
No very specific advice to give but this is what I do and then pull all
(compilable) topic branches into a "local" branch for complation. Just
wanted to remark that a definite downside is that switching branches a lot
also touches the tree a lot and hence tends to trigger quite unwelcome
amounts of recompiles. Using ccache would proably be effective in this
situation but I keep neglecting to check it out...
Rene
From: Jeff Garzik <hidden> Date: 2008-02-23 05:04:17
Daniel Barkalow wrote:
I find that the sequence of changes I make is pretty much unrelated to the
sequence of changes that end up in the project's history, because my
changes as I make them involve writing a lot of stubs (so I can build) and
then filling them out. It's beneficial to have version control on this so
that, if I screw up filling out a stub, I can get back to where I was.
Having made a complete series, I then generate a new series of commits,
each of which does one thing, without any bugs that I've resolved, such
that the net result is the end of the messy history, except with any
debugging or useless stuff skipped. It's this series that gets merged into
the project history, and I discard the other history.
The real trick is that the early patches in a lot of series often refactor
existing code in ways that are generally good and necessary for your
eventual outcome, but which you'd never think of until you've written more
of the series.
That summarizes well how I do original development, too. Whether its a
branch of an existing repo, or a newly cloned repo, when working on new
code I will do a first pass, committing as I go to provide useful
checkpoints.
Once I reach a satisfactory state, I'll refactor the patches so that
they make sense for upstream submission.
Jeff
On Fri, Feb 22, 2008 at 06:37:14PM -0600, Chase Venters wrote:
It seems to me that having multiple working trees (effectively, cloning
the "master" repository every time I need to make anything but a trivial
change) would be most effective under git as well as it doesn't require
creating messy, intermediate commits in the first place (but allows for them
if they are used). But I wonder how that approach would scale with a project
whose git repo weighed hundreds of megs or more. (With a centralized rcs, of
course, you don't have to lug around a copy of the whole project history in
each working tree.)
Take a look at git-new-workdir in git's contrib directory. I'm using it a
lot now. It makes it possible to set up as many workdirs as you want, sharing
the same repo. It's very dangerous if you're not rigorous, but it saves a lot
of time when you work on several branches at a time, which is even more true
for a project's documentation. The real thing to care about is not to have
the same branch checked out at several places.
Regards,
Willy
From: Sam Ravnborg <hidden> Date: 2008-02-23 09:10:29
On Fri, Feb 22, 2008 at 06:37:14PM -0600, Chase Venters wrote:
I've been making myself more familiar with git lately and I'm curious what
habits others have adopted. (I know there are a few documents in circulation
that deal with using git to work on the kernel but I don't think this has
been specifically covered).
My question is: If you're working on multiple things at once, do you tend to
clone the entire repository repeatedly into a series of separate working
directories and do your work there, then pull that work (possibly comprising
a series of "temporary" commits) back into a separate local master
respository with --squash, either into "master" or into a branch containing
the new feature?
The simple (for me) workflow I use is to create a clone of the
kernel for each 'topic' I work on.
So at the same time I may have one or maybe up to five clones of the
kernel.
When I want to combine thing I use git format-patch and git am.
Often there is some amount of editing done before combining stuff
especially for larger changes where the first in the serie is often
preparational work that were identified in random order when I did
the inital work.
Sam
From: Mike Hommey <hidden> Date: 2008-02-23 09:46:16
On Fri, Feb 22, 2008 at 11:10:48PM -0500, Daniel Barkalow wrote:
I find that the sequence of changes I make is pretty much unrelated to the
sequence of changes that end up in the project's history, because my
changes as I make them involve writing a lot of stubs (so I can build) and
then filling them out. It's beneficial to have version control on this so
that, if I screw up filling out a stub, I can get back to where I was.
Having made a complete series, I then generate a new series of commits,
each of which does one thing, without any bugs that I've resolved, such
that the net result is the end of the messy history, except with any
debugging or useless stuff skipped. It's this series that gets merged into
the project history, and I discard the other history.
The real trick is that the early patches in a lot of series often refactor
existing code in ways that are generally good and necessary for your
eventual outcome, but which you'd never think of until you've written more
of the series. Generating a new commit sequence is necessary to end up
with a history where it looks from the start like you know where you're
going and have everything done that needs to be done when you get to the
point of needing it. Furthermore, you want to be able to test these
commits in isolation, without the distraction of the changes that actually
prompted them, which means that you want to have your working tree is a
state that you never actually had it in as you were developing the end
result.
This means that you'll usually want to rewrite commits for any series that
isn't a single obvious patch, so it's not a big deal to commit any time
you want to work on some different branch.
I do that so much that I have this alias:
reorder = !sh -c 'git rebase -i --onto $0 $0 $1'
... and actually pass it only one argument most of the time.
Mike
From: Tommy Thorn <hidden> Date: 2016-06-15 22:44:16
Chase Venters wrote:
My question is: If you're working on multiple things at once, do you tend to
clone the entire repository repeatedly into a series of separate working
directories and do your work there, then pull that work (possibly comprising
a series of "temporary" commits) back into a separate local master
respository with --squash, either into "master" or into a branch containing
the new feature?
IMO, that approach scales poorly and involves a lot of overhead.
Or perhaps you create a temporary topical branch for each thing you are
working on, and commit arbitrary changes then checkout another branch when
you need to change gears, finally --squashing the intermediate commits when a
particular piece of work is done?
From: Steven Walter <hidden> Date: 2016-06-15 22:44:16
On Fri, Feb 22, 2008 at 06:37:14PM -0600, Chase Venters wrote:
My question is: If you're working on multiple things at once, do you tend to
clone the entire repository repeatedly into a series of separate working
directories and do your work there, then pull that work (possibly comprising
a series of "temporary" commits) back into a separate local master
respository with --squash, either into "master" or into a branch containing
the new feature?
Or perhaps you create a temporary topical branch for each thing you are
working on, and commit arbitrary changes then checkout another branch when
you need to change gears, finally --squashing the intermediate commits when a
particular piece of work is done?
I favor the second approach: single working copy, multiple branches. My
feeling is that wanting multiple workspaces is a holdover from using
subversion. For me, it is much faster to "git commit -a -m wip"
and then switch branches, than it would be to clone a whole new
repository and manage the inter-repository relationships.
Don't get so down on the "intermediate commits," either. For one,
whenever I switch back to a branch with a "wip" commit, I usually do a
"git reset HEAD^" to remove it and get my working tree back where it
was. There are also nifty tools like interactive rebase that assist
you in rewriting history to produce a set of clean, atomic commits.
It's not imperative to make your first draft perfection in git.
[...]
Insight appreciated, and I apologize if I've failed to RTFM somewhere.
No worries, I remember being in your situation once. git opens up
a host of opportunities with its flexibility, and getting started I
was consistently stumped by which of the many paths I should choose.
--
-Steven Walter [off-list ref]
Freedom is the freedom to say that 2 + 2 = 4
B2F1 0ECC E605 7321 E818 7A65 FC81 9777 DC28 9E8F
From: Jakub Narebski <hidden> Date: 2016-06-15 22:44:16
[removed linux-kernel list from Cc]
Chase Venters [off-list ref] writes:
My question is: If you're working on multiple things at once, do you
tend to clone the entire repository repeatedly into a series of
separate working directories and do your work there, then pull that
work (possibly comprising a series of "temporary" commits) back into
a separate local master respository with --squash, either into
"master" or into a branch containing the new feature?
Alternate solution is to use multiple working trees (multiple working
directories) with single repository, although it is still a bit
fragile; you should take care to not checkout same branch multiple
times. IIRC when discussing ".git" as a file representing symlink,
there were some discussion on how to improve multiple-workspaces
workflow.
Or perhaps you create a temporary topical branch for each thing you
are working on, and commit arbitrary changes then checkout another
branch when you need to change gears, finally --squashing the
intermediate commits when a particular piece of work is done?
I personally prefer this workflow, but I do not work as a main
contributor nor maintainer of large project.
As to intermediate commits: if you feel the need to interrupt your
work which is not quite ready for final commit, you can either use
"git stash" command, or commit it as WIP commit, then when going back
just "git commit --amend" it.
Moreover, when working on some larger topic, which needs to be split
into individual commits for beter history clarity, and for better
bisectability, you usually rewrite history before submitting
(publishing) your changes. You usually have to reorder commits (for
example moving improvements to infrastructure before commits
introducing new feature), split commits (separating just noticed
bugfix from a feature commit), squash commits (joining feature commit
and its bugfix) etc. You can use "git rebase --interactive" for that,
or one of Quilt-like patch management interfaces for git: StGit (which
I personally use) or Guilt (idea based on mq: Mercurial queues
extension).
[...]
It seems to me that having multiple working trees (effectively, cloning
the "master" repository every time I need to make anything but a trivial
change) would be most effective under git as well as it doesn't require
creating messy, intermediate commits in the first place (but allows for them
if they are used). But I wonder how that approach would scale with a project
whose git repo weighed hundreds of megs or more. (With a centralized rcs, of
course, you don't have to lug around a copy of the whole project history in
each working tree.)
You can always clone using --shared option to set-up alternates; this
way only new objects (new commits) would be stored in the clone. This
of course need for clone and source to be on the same filesystem.
By default git-clone on local filesystem uses hardlinks, so it also
should not be so hard on disk space.
--
Jakub Narebski
Poland
ShadeHawk on #git