Git Cookbook (for GCC developers)

This is a work in progress.

See https://gcc.gnu.org/git.html and https://gcc.gnu.org/gitwrite.html for the official documentation. The contrib/gcc-git-customization.sh script can be used to configure some helpful commands and settings, as described in the official docs.

Basic Workflow

Getting a copy of the repository

[ Permalink ]

To make a clone of the official GCC repository in the directory ~/src/gcc run:

git clone git://gcc.gnu.org/git/gcc.git ~/src/gcc

If you omit the last argument the clone will be created in a directory called gcc (because the last component of the URL is gcc.git).

If you have commit access to the GCC repository, use the URL git+ssh://username@gcc.gnu.org/git/gcc.git instead, where username is your account name on gcc.gnu.org (as always with SSH, you can omit the "username@" part if it's the same as your username on localhost or if you've configured a User for Host gcc.gnu.org in ~/.ssh/config).

Not getting lost

[ Permalink ]

Get into the habit of running:

git status

Do this all. the. time. It tells you which branch you're on and the status of the files in the working dir and the repository (and "the index", which is a staging area for changes that have been added but not yet committed).

Updating the repository

[ Permalink ]

If you have not changed any of the files in the repo, you can update your clone to match the upstream repo with:

git pull

Committing to 'master'

[ Permalink ]

The mainline development branch is called master (this corresponds to the trunk in the old Subversion repository).

TODO

Backporting a patch to a release branch

[ Permalink ]

Find the commit ID of the change to backport, for example by looking through the changes to one (or more) of the files affected:

git log FILE...

Scroll through the logs until you find the relevant commit, and make a note of its commit ID (the sha-1 hash). Let's assume this ID is 1234abcd.

Check out the release branch1:

git checkout releases/gcc-9

If you've used the contrib/gcc-git-customization.sh script then you can use the gcc-backport alias to do the backport:

git gcc-backport 1234abcd

That should be it. Review what you've done (git status and git show) and then git push if you're happy with it.

If you haven't used contrib/gcc-git-customization.sh to add the gcc-backport alias then you will have to do it manually, as described below.

Apply the change from the master branch using the commit ID you found earlier:

git cherry-pick -x -n 1234abcd

The -x option adds a ""(cherry picked from commit 1234abcd)" message to the commit log. The -n option will change the files in your work dir, and stage those changes to be committed, but stop before actually committing.

If the changes didn't apply cleanly, you will get an error message about conflicts in one or more files. The changes will have been applied to the working tree, with conflict markers left in the files that didn't merge cleanly. You will need to edit those files to remove the merge conflicts (either manually, or using a 3-way merge tool like kdiff3 or vimdiff). After removing the conflicts use git add FILE... to add the resolved files to the staging area.

When backporting a patch that was committed before 2020-05-27 you will probably need to revert the backported changes to ChangeLog files, because those files are no longer edited manually. The list of ChangeLogfiles involved in the backport can be found using:

git diff --staged --stat | grep --only-matching [^[:space:]]*ChangeLog`

If there are any ChangeLog files shown, use git checkout HEAD FILE... with that list of files to restore their previous state. With GNU xargs you can use the --no-run-if-empty option to do it in a single command:

git diff --staged --stat | grep --only-matching [^[:space:]]*ChangeLog` | xargs --no-run-if-empty git checkout HEAD

Now you can review your changes and push them.

Tips & Tricks

[ Permalink ]

Displaying dates with a fixed time zone

[ Permalink ]

When Git records the time of a commit it also stores the committer's time zone, and commands like git log will display dates in the relevant time zone by default.

If you want git log to show all dates with the same time zone, use the --date=local option:

git log --date=local

This will display dates using your current time zone, as specified by the TZ environment variable. To display all dates in UTC, you can do:

TZ=UTC+0 git log --date=local

You cannot tell Git to always use a particular time zone, but you can avoid having to use --date=local every time by setting the log.date config option:

git config log.date local

There are several other date formats supported, including iso-local, iso, rfc, and relative. You can use strftime formats too e.g. --date=format:%c or "--date=format-local:%D %r".


Footnotes

  1. using a separate worktree for the release branch can be helpful. (1)

None: GitCookbook (last edited 2020-07-14 09:03:29 by JonathanWakely)