Simon Josefsson <[EMAIL PROTECTED]> wrote: > Jim Meyering <[EMAIL PROTECTED]> writes: >> Now that the cvs-to-git gateway is set up, I am ready to switch >> gnulib development to git. > > I like it. > >> There are probably tools and services (web?) that rely on having >> an actual CVS repository, but people who care about those can take >> it upon themselves to adapt them to git -- or to the git/cvs >> emulation, if needed. > > I'll change the daily autobuilder to use git. > >> Once we agree to make the switch, I'll add a CVS commit hook to >> block all commits. That will ensure that no one accidentally >> commits a change from an old CVS work area. > > How would I commit things to the new git repository? Are there any > instructions available?
Hi Simon, I'll post a new how-to separately, but you've prompted me to write the following: A few months ago, I posted some quick how-to things, along with pointers to documentation. Bruno posted some, too. BTW, don't spend much (if any) time with cogito. It's on the way out, since its functionality has mostly been moved into git proper. Also, once you use git, you needn't bother with stgit, guilt, quilt, etc.[*] However, I have one strong preference that I haven't yet mentioned: ===================================== Be careful not to push merge commits. ===================================== What that means is when using git, we should see a single string of change sets on the trunk, just as we did in CVS. Each "commit" should have exactly one predecessor and one successor. 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. You could have avoided it by using a topic branch. Here's how: Say you checked out gnulib like this: git clone git://git.sv.gnu.org/gnulib then cd'd into it and ran: git checkout -b my-topic that creates the my-topic branch and puts you on it. To see which you're on, type "git branch". Right after the clone, you were on "master" (aka the trunk). To get back to the trunk, do this: git checkout master Note 1: Be careful to run "git pull" only when on the "master" branch, not when on a branch. I think that with the very latest version of git, you can't cause trouble if you forget, so be sure you're using 1.5.3.1 or newer. ] Note 2: It's best not to try to switch from one branch to another if you have pending (uncommitted) changes. Sometimes it works, sometimes the checkout will fail, telling you that your local modifications conflict with changes required to switch branches. Anyhow, get back onto your just-created branch: git checkout my-topic Now, modify some file and commit it: git commit some-file.c I find it useful to put the ChangeLog entries *only* in the commit log, initially, unless you plan to commit/push right away. Otherwise, you'll get more merge conflicts. So, you've committed a change. But it's only in your local repository, and only on your "my-topic" branch. Remembering our example, let's wait a day, and see that someone else changed something and pushed it to the public repository. Now, you want to update your trunk and "rebase" your changes on the branch so that they are once again relative to the tip of the trunk. Currently, your branch is attached to the trunk at the next-to-last change set. First: update the trunk from the public repo: [you've first made sure that "git diff" produces no output] git checkout master git pull Now, return to your branch, and "rebase" relative to trunk (master): git checkout my-topic git rebase master If there are no conflicts, this requires no more work from you. However, let's say there was one in ChangeLog, since you didn't follow my advice and modified it anyway. git rebase will tell you there was a conflict and in which file, and instruct you to resolve it and then resume with "git rebase --continue" once that's done. So you resolve as usual, by editing ChangeLog (which has the usual conflict markers), then type "git rebase --continue". That will fail, with a diagnostic telling you to mark the file as "conflict resolved" by doing this: git add ChangeLog Then, finally, you can proceed (possibly onto more conflict resolution, if there are conflicts in other files): git rebase --continue Once it finishes, your changes on the branch are now relative to the tip of the trunk. ------------------------------ Moving changes from your topic branch to the trunk: =================================================== Here, I'm assuming you've just done the above, and your changes on the desired branch are directly applicable to the trunk. First, get on the trunk: git checkout master Make sure there are no new changes: [obviously there's a race here, so you can't be 100% sure to avoid merges...] git pull If the above *did* bring in new changes, go back to your branch and rebase again. Now, pull the just-rebased changes from your branch to ".", the current branch (master): git pull . my-topic If you did everything properly, there is no risk of conflict with the above "pull". Look at the result with "gitk" (or git-log) and make sure that there is indeed no merge: gitk If everything is ok, you can then do "git push" to publish your change set. Oops. If you took my advice, and deferred modifying the ChangeLog file, now is the time to copy your commit log entry into ChangeLog. Hmm.. but now what? Commit your ChangeLog change as a separate change set? I usually don't. Instead, I "amend" the change set to which it refers. git-add ChangeLog git commit --amend -e The above is slightly risky, in general, since it modifies an existing commit in your tree, rather than simply adding a new one. You must not do this to a commit that you've already pushed. If you do, you will be unable to push the result, because that would cause trouble for everyone who might have refs to that displaced commit. (it doesn't really modify a commit. it adds a new one and uses it in place of the old one). I hesitated to mention this, because of the risk, but it's just too useful. Use with care. The bottom line: that adjusts the "topmost" change set to include whatever additional changes you want. But you can do it only *before* (not after) you've pushed. One-line summary in log (followed by a blank line) ================================================= Once you're happy with the result, (again, view with "gitk") and make sure you have a good "one-line summary" as the first line of the log message. It's good to have a blank line in the log after that summary line, or else some tools concatenate all following non-blank lines into an annoyingly long string. Finally, you can do: git-push to publish your changes. Jim [*] if you use a new-enough version of git, you should no longer find stgit, guilt, quilt, etc. necessary. Instead, use "git rebase -i ..." to maintain your private patch sets.