bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: git commit guidelines for gnulib


From: Jim Meyering
Subject: Re: git commit guidelines for gnulib
Date: Tue, 18 Sep 2007 09:33:37 +0200

Bruno Haible <address@hidden> wrote:
>> How can that go wrong?
>> If you update (pull/fetch/whatever), make a change,
>> and commit (locally), but don't push right away...
>> Then, someone else makes a change, commits, and pushes theirs.
>> After that, you pull (using cvs model), and that induces a merge,
>> but there were no conflicts, so you then push the result.
>> However, if you look at the resulting graph with e.g., gitk, you'll see
>> that the change set before yours now has two successors:
>>
>>        Next
>>        / \
>>   other   yours
>>        \ /
>>        Prev
>>
>> That's unnecessary and ugly.
>
> Why do you consider this "unnecessary" and "ugly"? I thought that this non-
> linear merge situation was one of the situations that distinguish a
> distributed version control system from a centralized version control system.

Taking advantage of such complexity *unnecessarily* is what's ugly.
If you have two branches that you want to merge, and both are public,
then rebase isn't really an option, since it'd change all of the commit
hashes of the rebased branch.  In that case, the merge is essential.
When one branch (your topic branch) is private, you *can* rebase, and thus
avoid the merge.

Look at the ascii-art diagrams in the git-rebase man page.
That shows how to convert the above into the linear sequence:

  Prev - other - yours - Next

> When I make a change to my tree, commit it locally to distinguish it from
> subsequent changes, and then, after a week of testing with other changes,
> decide to commit it into "master", isn't such a "merge commit"/diamond commit
> unavoidable?

It *is* avoidable.  That's the whole point of rebasing.
rebasing is essentially adjusting your deltas so that they apply
with no fuzz, and no conflicts, to the latest version of the
parent branch.

> If not, what is the procedure that you recommend when I want
> to make some changes that work like this:
>   - change 1
>   - change 2
>   - fix to change 1
>   - fix to change 2
>   - change 3
>   - another fix to change 1
>   - now commit change1 with its two fixes ?

Do all of this on a topic branch, T.  I'm assuming you've committed
6 change sets to that branch.  Now, run "git-rebase -i master".
In that process, you can use the interface (via your editor) to
reorder change sets and to squash (merge) each fix into the
change set that it applies to.

That should leave you with three change sets on T:
  - change 1
  - change 2
  - change 3

To *push* just the first one to the public repo, change to the trunk,
pull all three change sets onto the trunk, then remove the
top two.  [I'm sure there's a better way, but that works]

  git-checkout master
  git-pull . T
  git-reset --hard HEAD~2

> When I work with other people in a versioning system, I have only two
> requirements:
>
>   1) People should try to proofread and test their changes before committing.
>
>   2) When something doesn't work, it should be clear who is to blame.
>
> Ad 1): we should encourage testing before commit. I have the feeling that
> the wish to avoid diamond commits creates a race to commit as soon as
> possible. And as I know from earlier experience, the habit to commit
> without testing or even without thinking leads to bad quality.
>
> Ad 2): Isn't is clear, even in a diamond commit, who is the latest committer?
> Namely, the one who did the diamond commit. Or are the records missing in this
> case, preventing clear determination of responsibility?

It's always clear who committed/authored what _regular_ deltas.
But merge changes are sometimes hidden/abbreviated, as "uninteresting".
That's another reason to avoid unnecessary merges.

However, when you push a change for which someone else is listed
as author/committer, it's not obvious you did the push -- but that
is unusual.

> II) What's the recommended way to make short-lived changes? Is a developer
>     forced to create a topic branch just for creating a typo in a comment?

No.  I guess that wasn't clear.
If you're simply going to pull,modify,commit,push --
all in a relatively short time, then there's no need for a branch.

And if you start making a small change on the trunk and it
turns into something larger, you can put it on a new branch
simply by running git-checkout -b new-branch-name && git-commit -a
(also see git-stash).

> III) git-checkout.
>>    ################################################################
>>    # A word of caution:
>>    # Changing from one branch to another is so easy, quick, and
>>    # quiet (especially if you're used to CVS or svn) that it's easy
>>    # to forget that a simple "git-checkout master" or "git-checkout BR"
>>    # can make massive changes to your working directory -- it all
>>    # depends solely on how many files differ between your BR and
>>    # the trunk.
>
> I would like to avoid using "git checkout" to switch from one branch to
> another in the same directory. Simply, I'm more comfortable working in
> different directories. I assume it makes it easier to remember what is where,
> and to avoid doing mistakes. Right now, I use 5 checkouts of gnulib:
>   gnulib-cvs
>   gnulib-work
>   gnulib-unistring
>   gnulib-modified
>   gnulib-manytests
> and more on demand. But I obviously don't want to have 5 copies of the large
> git repository, only 5 checkouts. I heard somewhere that it would work to
> make symbolic links
>   gnulib-xxx/.git -> gnulib-cvs/.git

Correct.  You shouldn't use manual symlinks.
As Eric said, use git-clone's options to share the repository.
In the latest git, hard-linking is the default for a clone
using a local dir name.

BTW, if you want a quick answer, asking on irc (#git @ irc.freenode.net)
or the git mailing list will probably get a good one.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]