Welcome to the Git Wine tutorial! This page describes how to manage Wine code and patches with [https://git-scm.com/ Git]. Git is a fast version control system, originally written for use with large repositories, such as the Linux Kernel source. The Git Wine tree gives you fast access to the entire Wine tree and its history, and allows you to maintain a local tree or patch series and merge it easily with WineHQ.

+

Welcome to the Git Wine tutorial! This page describes how to manage Wine code and patches with [https://git-scm.com/ Git]. Git is a fast version control system, originally written for use with large repositories, such as the Linux Kernel source. The Git Wine tree gives you fast access to the entire Wine tree and its history, and allows you to maintain a local tree or patch series and merge it easily with WineHQ.

== Tutorials and guides ==

== Tutorials and guides ==

Line 13:

Line 13:

* [http://tom.preston-werner.com/2009/05/19/the-git-parable.html The Git Parable] "will take you on a journey through the creation of a Git-like system from the ground up" (May 2009).

* [http://tom.preston-werner.com/2009/05/19/the-git-parable.html The Git Parable] "will take you on a journey through the creation of a Git-like system from the ground up" (May 2009).

−

'''Note:''' To get documentation on a Git command, use `git help` or `man`. For example, the following two commands are equivalent:

+

'''Note:''' To get documentation on a Git command, use <code>git help</code> or <code>man</code>. For example, the following two commands are equivalent:

git help format-patch

git help format-patch

Line 22:

Line 22:

=== Downloading and installing Git ===

=== Downloading and installing Git ===

−

It's recommended to install Git via your distribution's package manager. If you want to install from source, you can download the latest version of Git from https://www.kernel.org/pub/software/scm/git/ . It installs into ~/bin by default. See [https://git-scm.com/book/en/v2/Getting-Started-Installing-Git#Installing-from-Source the Pro Git book] for build instructions.

+

It's recommended to install Git via your distribution's package manager. If you want to install from source, you can download the latest version of Git from https://www.kernel.org/pub/software/scm/git/ . It installs into ~/bin by default. See [https://git-scm.com/book/en/v2/Getting-Started-Installing-Git#Installing-from-Source the Pro Git book] for build instructions.

=== Cloning the Wine Git repository ===

=== Cloning the Wine Git repository ===

−

Checking out from the WineHQ Git repository:

+

You can browse the WineHQ Git repositories on the web at https://source.winehq.org/git. To download the main Wine repository:

git clone git://source.winehq.org/git/wine.git

git clone git://source.winehq.org/git/wine.git

Line 59:

Line 59:

* The '''HEAD''' (or '''tip''') of a branch is the most recent commit. On its own, HEAD means the tip of the current branch.

* The '''HEAD''' (or '''tip''') of a branch is the most recent commit. On its own, HEAD means the tip of the current branch.

* '''master''' is the main branch. SVN/CVS calls this "trunk".

* '''master''' is the main branch. SVN/CVS calls this "trunk".

−

* The '''parent''' of a commit is the one before it in the history. (Commits can technically have more than one parent, but the Wine repo avoids using this feature, preferring a linear history.) Given a commit `X`, its parent is referred to as `X^`, and its great-grandparent is referred to as `X^^^` or `X~3`.

+

* The '''parent''' of a commit is the one before it in the history. (Commits can technically have more than one parent, but the Wine repo avoids using this feature, preferring a linear history.) Given a commit <code>abcde</code>, its parent is referred to as <code>abcde^</code>, and its great-grandparent is referred to as <code>abcde^^^</code> or <code>abcde~3</code>.

* A '''repository''' (or '''repo''') is a database storing the source code of every available version of a program, and the author of every change.

* A '''repository''' (or '''repo''') is a database storing the source code of every available version of a program, and the author of every change.

* A '''tree''' is a git technical term meaning "directory" (sort of), and sometimes means the whole codebase of a project ("the Wine tree").

* A '''tree''' is a git technical term meaning "directory" (sort of), and sometimes means the whole codebase of a project ("the Wine tree").

Line 65:

Line 65:

== Managing your changes - the simple way ==

== Managing your changes - the simple way ==

−

=== Commiting a patch into your local tree ===

+

=== Committing a change into your local tree ===

After editing the checked out tree, you can use [https://www.kernel.org/pub/software/scm/git/docs/git-status.html git status] to see which files have changed:

After editing the checked out tree, you can use [https://www.kernel.org/pub/software/scm/git/docs/git-status.html git status] to see which files have changed:

Line 74:

Line 74:

git diff

git diff

−

To then commit '''all''' changed files to your local tree, use the [https://www.kernel.org/pub/software/scm/git/docs/git-commit.html git commit] command with the -a option:

+

To then commit ''all'' changed files to your local tree, use the [https://www.kernel.org/pub/software/scm/git/docs/git-commit.html git commit] command with the -a option:

git commit -a

git commit -a

Line 87:

Line 87:

git commit

git commit

+

'''Commit early, commit often''': Your local Git tree is yours. You should feel free to commit patches frequently, as it's not until you mail them in that they have a chance of being committed upstream.

+

=== Seeing where you are and what you've done ===

You can get a list of all the commits in the tree using [https://www.kernel.org/pub/software/scm/git/docs/git-whatchanged.html git whatchanged] or [https://www.kernel.org/pub/software/scm/git/docs/git-log.html git log]:

You can get a list of all the commits in the tree using [https://www.kernel.org/pub/software/scm/git/docs/git-whatchanged.html git whatchanged] or [https://www.kernel.org/pub/software/scm/git/docs/git-log.html git log]:

git whatchanged # list of commits, which shows what files were altered

git whatchanged # list of commits, which shows what files were altered

git log # list of commits

git log # list of commits

+

git log --decorate # list of commits, with the last upstream commit marked

git log --stat # list of commits, with diffstats

git log --stat # list of commits, with diffstats

git log --stat -p # list of commits, with diffstats and patches

git log --stat -p # list of commits, with diffstats and patches

−

=== Commit early, commit often ===

+

You can get a list of files that you have changed but have not yet committed using [https://www.kernel.org/pub/software/scm/git/docs/git-status.html git status]:

−

Your local git tree is yours. You should feel free to commit patches frequently, as it's not until you mail them in that they have a chance of being committed upstream.

+

+

git status # list of uncommitted changes

+

+

There's a nice tool to view your Git repository named [https://www.kernel.org/pub/software/scm/git/docs/gitk.html gitk], written in tcl/tk. AJ suggests using something like <code>gitk wine-1.0..</code> to make it go faster (please note that the trailing <code>..</code> is important). gitk visualizes both committed and uncommitted changes.

+

+

[https://sourceforge.net/projects/qgit/ qgit] also provides similar functionality, but in a Qt based interface. It appears to be faster than gitk and has additional features such as an annotation facility to identify which change introduced each line of a file.

+

+

If you prefer using your terminal, [https://lwn.net/Articles/390701/ "git lol" and "git lola"] are useful aliases you can add to your ~/.gitconfig file:

+

<pre>

+

[alias]

+

lol = log --graph --decorate --pretty=oneline --abbrev-commit

+

lola = log --graph --decorate --pretty=oneline --abbrev-commit --all

+

</pre>

+

+

If you have a webserver running, git instaweb allows you to view your local tree in your web browser.

=== Reverting changes in your working copy ===

=== Reverting changes in your working copy ===

Line 128:

Line 145:

This will open your editor, with a list of commits prefixed with '''pick'''. To delete a commit, just remove its line. To reorder them, just rearrange the lines. To edit commits, change '''pick''' to '''edit'''.

This will open your editor, with a list of commits prefixed with '''pick'''. To delete a commit, just remove its line. To reorder them, just rearrange the lines. To edit commits, change '''pick''' to '''edit'''.

−

Be sure to follow the instructions carefully when doing git-rebase -i. Specifically, when you are editing a commit (that you explicitly requested to edit) and are satisfied with the changes, you must use:

+

Be sure to follow the instructions carefully when doing <code>git rebase -i</code>. Specifically, when you are editing a commit (that you explicitly requested to edit) and are satisfied with the changes, you must use:

git add <file1> <file2>...

git add <file1> <file2>...

Line 134:

Line 151:

git rebase --continue

git rebase --continue

−

However, when `git-rebase -i` asks you to edit a commit that you have not requested to edit (e.g. there is a conflict), you must use:

+

However, when <code>git-rebase -i</code> asks you to edit a commit that you have not requested to edit (e.g. there is a conflict), you must use:

git add file1 file2...

git add file1 file2...

Line 178:

Line 195:

git branch -D tmp # clean up the temporary branch

git branch -D tmp # clean up the temporary branch

−

and the commit is gone. You need to checkout all the changed files though and the rebase may throw some errors for you to resolve as it applies later commits.

+

and the commit is gone. You need to checkout all the changed files though and the rebase may throw some errors for you to resolve as it applies later commits.

=== Removing trailing whitespace ===

=== Removing trailing whitespace ===

Line 187:

Line 204:

"It fixes whitespace on all the commits that you've made. I think it's pretty good about merge conflicts due to whitespace as well. I don't know of a way of doing this at commit time though."

"It fixes whitespace on all the commits that you've made. I think it's pretty good about merge conflicts due to whitespace as well. I don't know of a way of doing this at commit time though."

−

This is essential for submitting your patches to the Wine project. Please see this post for more information from Mike himself: https://www.winehq.org/pipermail/wine-devel/2010-July/084870.html

+

This is essential for submitting your patches to the Wine project. Please see this post for more information: https://www.winehq.org/pipermail/wine-devel/2010-July/084870.html

−

Trailing whitespace is highlighted in the output of the [https://www.kernel.org/pub/software/scm/git/docs/git-diff.html git diff] command when colored output is enabled (more about this in the [#further_configuration Further configuration] section).

+

Trailing whitespace is highlighted in the output of the [https://www.kernel.org/pub/software/scm/git/docs/git-diff.html git diff] command when colored output is enabled (more about this in the [[#Further_configuration|Further configuration]] section).

+

+

=== Keeping up to date with WineHQ ===

+

Now that you have a copy of the Wine Git repository, you will periodically need to receive new commits from the original repository. You do this using:

+

+

git pull --rebase

+

+

This is equivalent to:

+

+

git fetch

+

git rebase origin

+

+

[https://www.kernel.org/pub/software/scm/git/docs/git-fetch.html git fetch] retrieves new files from the WineHQ Git repository; this should always be a safe operation as it does not change your local file system.

+

+

[https://www.kernel.org/pub/software/scm/git/docs/git-rebase.html git rebase] origin reapplies any local commits you have made onto the latest WineHQ branch. (Technically, it creates a new branch on 'origin', reapplies all the patches in your current HEAD to the new branch, then changes HEAD to the new branch.) Patches already applied upstream will not be reapplied.

+

+

A common mistake is to use <code>git fetch</code> by itself. It will only download updates but will not apply them. Another common problem is trying to rebase while having uncommitted changes. One way to fix this is to:

+

+

git commit -a # commit changes

+

git rebase origin # rebase

+

git reset HEAD^ # uncommit changes

+

+

When you send patches, inevitably, some of your patches will be rejected, while others will be accepted. If you have written a series of patches, but only some of those are rejected, it can be annoying to reorder them, fix one or two problems and resubmit. The main git tools that you can use to help solve this problem are [https://www.kernel.org/pub/software/scm/git/docs/git-rebase.html git rebase] and [https://www.kernel.org/pub/software/scm/git/docs/git-cherry-pick.html git cherry-pick]. See [https://www.kernel.org/pub/software/scm/git/docs/howto/rebase-from-internal-branch.txt here] for a discussion on the Git mailing list about rebasing on local branches.

+

+

=== Resolving merge conflicts ===

+

When rebasing, sometimes upstream changes prevent your patches from applying. If there is a conflict, you will see something like this:

+

<pre>

+

Applying <patchname>

+

error: patch failed: <file>:<line>

+

error: <file>: patch does not apply

+

Using index info to reconstruct a base tree...

+

Falling back to patching base and 3-way merge...

+

Auto-merged <file>

+

CONFLICT (content): Merge conflict in <file>

+

Failed to merge in the changes.

+

Patch failed at <msgnum>.

+

When you have resolved this problem run "git rebase --continue".

+

If you would prefer to skip this patch, instead run "git rebase --skip".

+

To restore the original branch and stop rebasing run "git rebase --abort".

+

</pre>

+

+

There are two choices now: resolve the conflict or skip the patch. The file in question will contain conflict markers where the patch failed:

+

<pre>

+

<<<<<<<

+

[code that caused patch not to be applied]

+

=======

+

[what would have been here if the patch had been applied]

+

>>>>>>>

+

</pre>

+

+

To resolve the conflict you have to manually merge the code between the conflict markers, leaving the file in a compilable state. After that, run

+

+

git add <file>

+

git rebase --continue

+

+

to remove the merge-conflict state and continue with the operation.

+

+

Patches can be skipped as follows:

+

+

(git reset --hard # removes the patch)

+

git rebase --skip

=== Sending patches: generating a patchset ===

=== Sending patches: generating a patchset ===

−

After checking in your local changes (in multiple small commits), you can generate a list of the patches you need to send upstream (i.e. to wine-patches) with the [https://www.kernel.org/pub/software/scm/git/docs/git-format-patch.html git format-patch] command:

+

After checking in your local changes (in multiple small commits), you can generate a list of the patches you need to send upstream (i.e. to wine-devel) with the [https://www.kernel.org/pub/software/scm/git/docs/git-format-patch.html git format-patch] command:

git format-patch origin

git format-patch origin

−

"origin" is short for "origin/master", the default name of the upstream WineHQ branch. One file per patch will be created in the current directory. You can change the output directory with `-o <directory>`, for example `-o out` to save the patches in the '''out''' directory.

+

"origin" is short for "origin/master", the default name of the upstream WineHQ branch. One file per patch will be created in the current directory. You can change the output directory with <code>-o <directory></code>, for example <code>-o out</code> to save the patches in the '''out''' directory.

−

+

−

You can also add `--subject-prefix=""` to avoid getting the word `PATCH` in all your email subjects (i.e. `[PATCH x/y]`).

+

−

'''Important:''' If you have not read it already, please read SubmittingPatches.

+

'''Important:''' If you have not read it already, please read [[Submitting Patches]].

==== Adding a cover letter ====

==== Adding a cover letter ====

−

Passing the `--cover-letter` option to `git format-patch` allows you to create a "patch 0" that describes the patchset. This first "patch file" contains no actual changes, but can be easily sent as an email before the real patches.

+

Passing the <code>--cover-letter</code> option to <code>git format-patch</code> allows you to create a "patch 0" that describes the patchset. This first "patch file" contains no actual changes, but can be easily sent as an email before the real patches.

==== Sending the patches using SMTP ====

==== Sending the patches using SMTP ====

−

Before you can use the `git send-email` command, you have to add information about your SMTP server to ~/.gitconfig. For example, if you are sending from Gmail, put:

+

Before you can use the <code>git send-email</code> command, you have to add information about your SMTP server to ~/.gitconfig. For example, if you are sending from Gmail, put:

<pre>

<pre>

[sendemail]

[sendemail]

Line 219:

Line 294:

git send-email *.patch

git send-email *.patch

−

If you want to check your patches first (e.g. to alter the subject line), just use the `--annotate` option to `git send-email`.

+

If you want to check your patches first (e.g. to alter the subject line), just use the <code>--annotate</code> option to <code>git send-email</code>.

Using Mozilla, sending patches is then just a matter of clicking on "Edit Draft", reviewing the mail and then clicking "Send". If you're using Evolution, you can drag and drop the .patch files into your drafts folder. Patches in the Drafts folder will have the date and time of the timestamp of the commit, hence if you generate multiple times you will have many copies of the same patch with the same date and time. This will be the case until you amend the commit and get a new commit timestamp.

+

Using Mozilla, sending patches is then just a matter of clicking on "Edit Draft", reviewing the mail and then clicking "Send". If you're using Evolution, you can drag and drop the .patch files into your drafts folder. Patches in the Drafts folder will have the date and time of the timestamp of the commit, hence if you generate multiple times you will have many copies of the same patch with the same date and time. This will be the case until you amend the commit and get a new commit timestamp.

−

'''Important:''' Many email clients will alter your email in ways that will prevent them from applying. For example, Thunderbird will wrap emails and send them with 'format=flowed', which will make them unusable by Git. For Thunderbird, you can follow [http://kb.mozillazine.org/Plain_text_e-mail_-_Thunderbird#Completely_plain_email these instructions] to send patches. If all else fails, you can add `--attach` to the `git format-patch` command to send the emails as attachments.

+

'''Important:''' Many email clients will alter your email in ways that will prevent them from applying. For example, Thunderbird will wrap emails and send them with 'format=flowed', which will make them unusable by Git. For Thunderbird, you can follow [http://kb.mozillazine.org/Plain_text_e-mail_-_Thunderbird#Completely_plain_email these instructions] to send patches. If all else fails, you can add <code>--attach</code> to the <code>git format-patch</code> command to send the emails as attachments.

−

Setting up ssh simplifies the patch generation by removing the need to enter a password. Use ssh-keygen to create your keys and copy ~/.ssh/id_rsa.pub to ~/.ssh/authorized_keys to allow the tunnel to be created without entering a password.

+

Setting up ssh simplifies the patch generation by removing the need to enter a password. Use ssh-keygen to create your keys and copy ~/.ssh/id_rsa.pub to ~/.ssh/authorized_keys to allow the tunnel to be created without entering a password.

Using local Thunderbird folders, you can use the following approach to add your patches to the Drafts folder (without using IMAP):

Using local Thunderbird folders, you can use the following approach to add your patches to the Drafts folder (without using IMAP):

Line 279:

Line 354:

Now, all you need to do is to set up a new receiving account in KMail that collects mail from /home/username/.maildir and filter emails coming in on that account to your drafts folder.

Now, all you need to do is to set up a new receiving account in KMail that collects mail from /home/username/.maildir and filter emails coming in on that account to your drafts folder.

−

=== Keeping up to date with the Wine Git repository ===

+

== Managing branches ==

−

So now you have a copy of the Wine Git tree, you need to get the patches Alexandre commits to WineHQ. You do this using:

+

[https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging Git branches] can be useful if you are working on a lot of bugs at the same time. However, they are completely optional and overkill if you are only working on one thing.

−

git pull --rebase

−

−

This is equivalent to:

−

−

git fetch

−

git rebase origin

−

−

[https://www.kernel.org/pub/software/scm/git/docs/git-fetch.html git fetch] retrieves new files from the WineHQ Git repository; this should always be a safe operation as it does not change your local file system.

−

−

[https://www.kernel.org/pub/software/scm/git/docs/git-rebase.html git rebase] origin reapplies any local commits you have made onto the latest WineHQ branch. (Technically, it creates a new branch on 'origin', reapplies all the patches in your current HEAD to the new branch, then changes HEAD to the new branch.) Patches already applied upstream will not be reapplied.

−

−

A common mistake is to use `git fetch` by itself. It will only download updates but will not apply them. Another common problem is trying to rebase while having uncommitted changes. To fix this you need to:

−

−

git commit -a # commit changes

−

git rebase origin # rebase

−

git reset HEAD^ # uncommit changes

−

−

When you send patches, inevitably, some of your patches will be rejected, while others will be accepted. If you have written a series of patches, but only some of those are rejected, it can be annoying to reorder them, fix one or two problems and resubmit. The main git tools that you can use to help solve this problem are [https://www.kernel.org/pub/software/scm/git/docs/git-rebase.html git rebase] and [https://www.kernel.org/pub/software/scm/git/docs/git-cherry-pick.html git cherry-pick]. See [https://www.kernel.org/pub/software/scm/git/docs/howto/rebase-from-internal-branch.txt here] for a discussion on the Git mailing list about rebasing on local branches.

−

−

=== Resolving merge conflicts ===

−

When rebasing, sometimes upstream changes prevent your patches from applying. If there is a conflict, you will see something like this:

−

<pre>

−

Applying <patchname>

−

error: patch failed: <file>:<line>

−

error: <file>: patch does not apply

−

Using index info to reconstruct a base tree...

−

Falling back to patching base and 3-way merge...

−

Auto-merged <file>

−

CONFLICT (content): Merge conflict in <file>

−

Failed to merge in the changes.

−

Patch failed at <msgnum>.

−

When you have resolved this problem run "git rebase --continue".

−

If you would prefer to skip this patch, instead run "git rebase --skip".

−

To restore the original branch and stop rebasing run "git rebase --abort".

−

</pre>

−

−

There are two choices now: resolve the conflict or skip the patch. The file in question will contain conflict markers where the patch failed:

−

<pre>

−

<<<<<<<

−

[code that caused patch not to be applied]

−

=======

−

[what would have been here if the patch had been applied]

−

>>>>>>>

−

</pre>

−

−

To resolve the conflict you have to manually merge the code between the conflict markers, leaving the file in a compilable state. After that, run

−

−

git add <file>

−

git rebase --continue

−

−

to remove the merge-conflict state and continue with the operation.

−

−

Patches can be skipped as follows:

−

−

(git reset --hard # removes the patch)

−

git rebase --skip

−

−

== Managing branches ==

=== Creating a branch ===

=== Creating a branch ===

To create a branch, use [https://www.kernel.org/pub/software/scm/git/docs/git-checkout.html git checkout] with the -b option. For example:

To create a branch, use [https://www.kernel.org/pub/software/scm/git/docs/git-checkout.html git checkout] with the -b option. For example:

Line 379:

Line 396:

git reset

git reset

−

=== Regression testing ===

=== Regression testing ===

−

Regression testing is really easy with Git. It's done with the help of [https://www.kernel.org/pub/software/scm/git/docs/git-bisect.html git bisect] that does all the magic. So all that's left to do is to compile and test. Even non-developers can do it. ''See [[Regression Testing]] for instructions.''

+

Regression testing is really easy with Git. It's done with the help of [https://www.kernel.org/pub/software/scm/git/docs/git-bisect.html git bisect] that does all the magic. So all that's left to do is to compile and test. Even non-developers can do it. ''See [[Regression Testing]] for instructions.''

−

+

−

=== Viewing the Git tree ===

+

−

You can browse the WineHQ Git repositories on the web at https://source.winehq.org/git. If you have a webserver running, [https://www.kernel.org/pub/software/scm/git/docs/git-instaweb.html git instaweb] allows you to view your local tree in your web browser.

+

−

+

−

There's a nice tool to view your Git repository named [https://www.kernel.org/pub/software/scm/git/docs/gitk.html gitk], written in tcl/tk. AJ suggests using something like `gitk wine-1.0..` to make it go faster (please note that the trailing `..` is important).

+

−

+

−

[https://sourceforge.net/projects/qgit/ qgit] also provides similar functionality, but in a Qt based interface. It appears to be faster than gitk and has additional features such as an annotation facility to identify which change introduced each line of a file.

+

−

+

−

If you prefer using your terminal, [https://lwn.net/Articles/390701/ "git lol" and "git lola"] are useful aliases you can add to your ~/.gitconfig file:

+

−

<pre>

+

−

[alias]

+

−

lol = log --graph --decorate --pretty=oneline --abbrev-commit

+

−

lola = log --graph --decorate --pretty=oneline --abbrev-commit --all

+

−

</pre>

+

=== Committer statistics ===

=== Committer statistics ===

Line 404:

Line 406:

=== Finding who changed what ===

=== Finding who changed what ===

−

git log /path/ # log of changes to files in /path/

git log /path/ # log of changes to files in /path/

git log /path/file # log of changes to /path/file

git log /path/file # log of changes to /path/file

Line 475:

Line 476:

== Annoyances ==

== Annoyances ==

−

It can be quite hard to get a real understanding of the underlying concepts of Git, and if you are a git newb you are almost certain to run into in a situation where things break and you have no idea how to get out of the mess. At this point: don't panic! You might be tempted to just trash your repository and manually remerge your patches, but it is very probable you will run into the same situation again so you'd be better off making sure you have understood how Git works. Look through the [#tutorials list of tutorials] at the top of this page.

+

It can be quite hard to get a real understanding of the underlying concepts of Git, and if you are a git newb you are almost certain to run into in a situation where things break and you have no idea how to get out of the mess. At this point: don't panic! You might be tempted to just trash your repository and manually remerge your patches, but it is very probable you will run into the same situation again so you'd be better off making sure you have understood how Git works. Look through the [[#Tutorials_and_guides|list of tutorials]] at the top of this page.

== Other Git repositories ==

== Other Git repositories ==

Revision as of 10:15, 10 November 2017

Welcome to the Git Wine tutorial! This page describes how to manage Wine code and patches with Git. Git is a fast version control system, originally written for use with large repositories, such as the Linux Kernel source. The Git Wine tree gives you fast access to the entire Wine tree and its history, and allows you to maintain a local tree or patch series and merge it easily with WineHQ.

Glossary

A commit (or changeset, or revision) is a snapshot of a codebase. Each commit has a name -- its commit id -- which is a SHA1 hash. Commits can have other names (tags, etc). See the "Specifying revisions" section of the git rev-parse page for details on how refer to commits. The verb to commit means to create a commit.

A diff is a file describing the differences between two sets of files. They are created with the command git diff. If you have code in the "before" state, you can apply the patch (with git apply) and you end up with code in the "after" state.

A patch is a file that includes authorship information, a description, and a diff. They are created with git format-patch and committed with git am. This similar to applying a patch, but it also creates a commit that preserves the original description and authorship information.

The HEAD (or tip) of a branch is the most recent commit. On its own, HEAD means the tip of the current branch.

master is the main branch. SVN/CVS calls this "trunk".

The parent of a commit is the one before it in the history. (Commits can technically have more than one parent, but the Wine repo avoids using this feature, preferring a linear history.) Given a commit abcde, its parent is referred to as abcde^, and its great-grandparent is referred to as abcde^^^ or abcde~3.

A repository (or repo) is a database storing the source code of every available version of a program, and the author of every change.

A tree is a git technical term meaning "directory" (sort of), and sometimes means the whole codebase of a project ("the Wine tree").

The working copy or working tree refers to the files and directories on your file system, the ones you can see and change with the file manager. The git status command will refer to changes to these files as "Changed but not updated".

Managing your changes - the simple way

Committing a change into your local tree

After editing the checked out tree, you can use git status to see which files have changed:

You can get a list of files that you have changed but have not yet committed using git status:

git status # list of uncommitted changes

There's a nice tool to view your Git repository named gitk, written in tcl/tk. AJ suggests using something like gitk wine-1.0.. to make it go faster (please note that the trailing .. is important). gitk visualizes both committed and uncommitted changes.

qgit also provides similar functionality, but in a Qt based interface. It appears to be faster than gitk and has additional features such as an annotation facility to identify which change introduced each line of a file.

Editing commits

To edit earlier commits (or reorder or delete them) use the -i (aka --interactive) option to git rebase. So if you are interested in altering the 5 most recent commits use:

git rebase -i HEAD~5

This will open your editor, with a list of commits prefixed with pick. To delete a commit, just remove its line. To reorder them, just rearrange the lines. To edit commits, change pick to edit.

Be sure to follow the instructions carefully when doing git rebase -i. Specifically, when you are editing a commit (that you explicitly requested to edit) and are satisfied with the changes, you must use:

git add <file1> <file2>...
git commit --amend
git rebase --continue

However, when git-rebase -i asks you to edit a commit that you have not requested to edit (e.g. there is a conflict), you must use:

git add file1 file2...
git rebase --continue

This is quite important - not following this carefully will result in merged patches.

Editing commits the hard way

Instructions for those who don't want to use git rebase -i:

If the commit is not the most recent one, but say 5th from the top then you can:

Trailing whitespace is highlighted in the output of the git diff command when colored output is enabled (more about this in the Further configuration section).

Keeping up to date with WineHQ

Now that you have a copy of the Wine Git repository, you will periodically need to receive new commits from the original repository. You do this using:

git pull --rebase

This is equivalent to:

git fetch
git rebase origin

git fetch retrieves new files from the WineHQ Git repository; this should always be a safe operation as it does not change your local file system.

git rebase origin reapplies any local commits you have made onto the latest WineHQ branch. (Technically, it creates a new branch on 'origin', reapplies all the patches in your current HEAD to the new branch, then changes HEAD to the new branch.) Patches already applied upstream will not be reapplied.

A common mistake is to use git fetch by itself. It will only download updates but will not apply them. Another common problem is trying to rebase while having uncommitted changes. One way to fix this is to:

When you send patches, inevitably, some of your patches will be rejected, while others will be accepted. If you have written a series of patches, but only some of those are rejected, it can be annoying to reorder them, fix one or two problems and resubmit. The main git tools that you can use to help solve this problem are git rebase and git cherry-pick. See here for a discussion on the Git mailing list about rebasing on local branches.

Resolving merge conflicts

When rebasing, sometimes upstream changes prevent your patches from applying. If there is a conflict, you will see something like this:

Applying <patchname>
error: patch failed: <file>:<line>
error: <file>: patch does not apply
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merged <file>
CONFLICT (content): Merge conflict in <file>
Failed to merge in the changes.
Patch failed at <msgnum>.
When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".

There are two choices now: resolve the conflict or skip the patch. The file in question will contain conflict markers where the patch failed:

<<<<<<<
[code that caused patch not to be applied]
=======
[what would have been here if the patch had been applied]
>>>>>>>

To resolve the conflict you have to manually merge the code between the conflict markers, leaving the file in a compilable state. After that, run

git add <file>
git rebase --continue

to remove the merge-conflict state and continue with the operation.

Patches can be skipped as follows:

(git reset --hard # removes the patch)
git rebase --skip

Sending patches: generating a patchset

After checking in your local changes (in multiple small commits), you can generate a list of the patches you need to send upstream (i.e. to wine-devel) with the git format-patch command:

git format-patch origin

"origin" is short for "origin/master", the default name of the upstream WineHQ branch. One file per patch will be created in the current directory. You can change the output directory with -o <directory>, for example -o out to save the patches in the out directory.

Adding a cover letter

Passing the --cover-letter option to git format-patch allows you to create a "patch 0" that describes the patchset. This first "patch file" contains no actual changes, but can be easily sent as an email before the real patches.

Sending the patches using SMTP

Before you can use the git send-email command, you have to add information about your SMTP server to ~/.gitconfig. For example, if you are sending from Gmail, put:

Using Mozilla, sending patches is then just a matter of clicking on "Edit Draft", reviewing the mail and then clicking "Send". If you're using Evolution, you can drag and drop the .patch files into your drafts folder. Patches in the Drafts folder will have the date and time of the timestamp of the commit, hence if you generate multiple times you will have many copies of the same patch with the same date and time. This will be the case until you amend the commit and get a new commit timestamp.

Important: Many email clients will alter your email in ways that will prevent them from applying. For example, Thunderbird will wrap emails and send them with 'format=flowed', which will make them unusable by Git. For Thunderbird, you can follow these instructions to send patches. If all else fails, you can add --attach to the git format-patch command to send the emails as attachments.
Setting up ssh simplifies the patch generation by removing the need to enter a password. Use ssh-keygen to create your keys and copy ~/.ssh/id_rsa.pub to ~/.ssh/authorized_keys to allow the tunnel to be created without entering a password.

Using local Thunderbird folders, you can use the following approach to add your patches to the Drafts folder (without using IMAP):

Navigating branches

git branch # local branches only
git branch -a # both local and remote branches

To change branches, use git checkout:

git checkout master # change to branch master

Merging and rebasing branches

Git allows you to merge branches together; this is not done in the WineHQ repository, so it is easier to just rebase/cherry-pick instead.

Deleting branches

git branch -D new-branch

Advanced branching

For more information on managing branches in git, see the Git Branches page.

Other useful operations

Picking patches from another branch

You can cherry pick (apply) a patch from another branch into your current branch using:

git cherry-pick <commit-id>

This will create a new commit, but with authorship information from the original patch.

Getting rid of timestamp changes

Git considers a file changed if its date is different from that in the Git index file. "git diff-index HEAD" may show files have changed if you have edited them and reverted the changes (or even just touched the file). You can remove this difference using:

git reset

Regression testing

Regression testing is really easy with Git. It's done with the help of git bisect that does all the magic. So all that's left to do is to compile and test. Even non-developers can do it. See Regression Testing for instructions.

Committer statistics

To see a list of committers in the last 5 years, sorted by number of commits:

Working with GitHub

Introduction

GitHub, through its ability to "fork" an existing project, provides a good way to work on the Wine project when, for example, the project itself is in "code freeze" due to proximity to a release milestone.

Once you have forked

Once forking is complete, you will find an SSH URL listed, that has read/write access, of the form:

git@github.com:username/wine.git

First, you must check out your new repository. To do so, type:

git clone git@github.com:username/wine.git

It is advantageous to add the WineHQ Git repository as an upstream repository, rather than the !GitHub mirror. Additionally, we will rebase with this repository to ensure that the HEAD of our repository is up to date with WineHQ. To do this, use the following commands:

Finally, if you would like to force commits onto !GitHub (e.g. edited patches), use:

git push -f origin master

Personally, I (MishaKoshelev) use the following each time I have some new patches that I would like to send to my !GitHub repository. This ensures that all patches are forced, and trailing whitespace is removed:

Patch stack

Stacked Git is similar to Quilt, just on top of Git. It manages a stack of applied and unapplied patches on top of a Git branch. Patches can be pushed on the applied stack or popped off the applied stack onto the unapplied stack. The topmost applied patch can be edited and the stack can be rebased onto an updated branch. This makes keeping around and refining local changesets (changeset->patch) until they are applied upstream much easier. The history of changes to a patch are also kept in Git.

Annoyances

It can be quite hard to get a real understanding of the underlying concepts of Git, and if you are a git newb you are almost certain to run into in a situation where things break and you have no idea how to get out of the mess. At this point: don't panic! You might be tempted to just trash your repository and manually remerge your patches, but it is very probable you will run into the same situation again so you'd be better off making sure you have understood how Git works. Look through the list of tutorials at the top of this page.