Git

From PmaWiki
Jump to: navigation, search

This is just a short guide to Git usage; at the bottom of the page you can find links to more documentation.

Contents

[edit] Before starting

Git uses name and email for identifying author of the commit. So it is a good idea to introduce yourself to Git:

 git config --global user.name "YOUR NAME"
 git config --global user.email "MAIL@DOMAIN"

More details on https://help.github.com/articles/set-up-git.

[edit] Obtaining code

Now you can clone the repository you want to work with:

 git clone https://github.com/phpmyadmin/phpmyadmin.git

More details on https://help.github.com/articles/fork-a-repo. Using https for cloning is the recommended method; it does not require you to set up SSH keys, and is firewall-friendly.

Cloning can take some time, but you only do this once per repository and then all repository history is stored on your disk.

If you don't want to get full history and do not intend to use git for anything else than looking into the code and recent history, you can perform a shallow checkout and limit how much history is being received by adding --depth parameter (eg. --depth 50). This repository won't be usable for pushing changes back, but you can use it to generate patches to send to upstream (see below).

Once you have cloned the repository you can use existing Git database to speed up creating new clones using --reference parameter:

 git clone https://github.com/phpmyadmin/phpmyadmin.git --reference /path/to/existing/phpmyadmin/checkout

[edit] Available repositories

The project has several git repositories, each serving a different purpose:

phpmyadmin.git
phpMyAdmin code.
website.git
Website code.
themes.git
Custom themes.
data.git
Various project related data (such as logos, T-shirt graphics, etc.).
history.git
Some historical documents (old changelogs or website).
planet.git
Planet phpMyAdmin configuration.
localized_docs.git
Localized documentation.

[edit] Committing

After you have made some changes you can commit them. Git allows you to pick which parts of your changes you want to commit using git add (or some of its variants like git add -i or git gui). After selecting what to commit just commit it using git commit.

To commit all changes in current repository just invoke git commit -a.

[edit] Commit messages

Please write a good commit message describing the changes. The first line serves as the subject so use it for short summary, then leave a blank line and write longer description if necessary. You can look at the git commit log in order to see previous messages. Some good messages include "Restore widget functionality when logged in as root (bug 4242)" or "Fix table spacing in user privilege report".

[edit] Updating repository

Once somebody else has made changes in the remote repository, you should fetch them:

 git pull

If you already have unpublished local changes, you might want to rebase them on top of repository changes (to avoid useless merge commits):

 git pull --rebase

[edit] Pushing changes

Once you have some changes to publish, you can push them to remote repository using:

 git push

Only fast forward pushes are allowed, so if your working copy is not up to date, you need to update it first (see above).

[edit] Working with branches

In phpMyAdmin, we use several branches to maintain already released versions. To see the names of the existing remote branches (the ones in central repository):

 git branch -r

To work on a different branch you need to create a local branch, which will track the remote one:

 git branch --track QA_3_3 origin/QA_3_3

Again, this needs to be done only once for each branch.

Once you did this, you can switch to that branch:

 git checkout QA_3_3

And you can work on it:

 # do the changes
 git commit -a  # commit
 git push # publish

[edit] Committing fixes to several branches

As the fixes usually need to go to several branches, it is a good idea to start with the most specific branch (eg. MAINT_3_3_0). Once you commit the fix there, just merge the branch to the parent. This way the commit will exist just once in the history and it will be clear that all bug fixes from MAINT/QA branches are merged in their parents (QA/master).

Basically the workflow should look like following:

git checkout MAINT_3_5_0
EDIT
git commit -m 'FIXED SOMETHING'
git checkout QA_3_5
git merge MAINT_3_5_0
git checkout master
git merge QA_3_5

[edit] Merging patches from third party contributors

It is always a good idea to record authorship of the code. For this reason Git allows you to specify the author name on commit by using --author parameter. You will be recorded as the committer, but authorship will be recorded:

 git commit --author="John Doe <john@example.net>"

[edit] Working on new features

It is not always a good idea to work on the master branch. If you plan to develop some bigger feature, it is good to create a so called feature branch, where you will work on it. As soon as the feature is completed, you can merge it to the master and publish it.

To create a new branch and check it out (from currently active one):

 git checkout -b feature_name

Now you can work and commit in this branch.

Once you think the feature is ready, you can merge it to master and publish:

 git checkout master     # Switch back to master branch
 git merge feature_name  # Merge feature branch
 git push origin master  # Publish master branch

If you want to make the feature branch publicly available, you can push it to the repository:

 git checkout feature_name       # Switch to feature branch
 git push origin feature_name    # Publish feature branch and make it tracking

Once the branch is published, you can not rebase it on top of current master. However you should do merges with master on any bigger changes there to follow current development:

 git checkout feature_name       # Switch to feature branch
 git merge master                # Merge back changes done in master

[edit] Looking at older revisions

To look at some commit, use git show:

 git show 6caa0de957f996cd3344e8b27658ce77d3e64f37

You can also use short revision hashes (anything that is unique is okay):

 git show 6caa0de

To show the second commit before current HEAD use:

 git show HEAD~2

You can also use git checkout instead of git show to get update working copy to match tree state at that time. Please note that if you commit in this state, all your commits will go to anonymous branch, which would be lost after you switch from it without naming it.

[edit] Finding problematic commit

If you know that something was working in one version and got broken in another, you can use git bisect to find the problematic commit.

To start bisect:

git bisect start BAD_REVISION GOOD_REVISION

Then on each step git checkouts some revision and you tell it by either git bisect good or by git bisect bad whether the revision is correct.

If the test can be coded, you can use git bisect run to find out the broken revision automatically.

After completing bisect, you might want to return back to HEAD, which can be done with git bisect reset.

Example session with git bisect:

$ git bisect start HEAD 8ef8f753cb45125db0f392d6ac4dc72daf0d8c2e
Bisecting: 9 revisions left to test after this (roughly 3 steps)
[30b63d142e523da28c2ad03c1524e976369485c2] Prevent js error in some cases after session expiration
$ git bisect good
Bisecting: 4 revisions left to test after this (roughly 2 steps)
[6caa0de957f996cd3344e8b27658ce77d3e64f37] Catalan update
$ git bisect good
Bisecting: 2 revisions left to test after this (roughly 1 step)
[6317006a34f79e83ef5220388d3271edb64cb989] Dutch update
$ git bisect good
Bisecting: 0 revisions left to test after this (roughly 1 step)
[3a91ca2fca939bf14e092a846757fdbcf053c42e] Dutch update
$ git bisect good
b3e8949af6315d1277e5955ada0a0cb2e73583c7 is the first bad commit
commit b3e8949af6315d1277e5955ada0a0cb2e73583c7
Author: Herman van Rink <rink@initfour.nl>
Date:   Wed Feb 17 11:59:58 2010 +0100

    test

:100644 100644 9ae378e36930206dab25d7ef2ec6d8873f061db7 2b441d9e45ec74a6efc980bf7f05ca57c3ba5f06 M	ChangeLog


[edit] Publishing changes for merge

If you are not (yet) a team member and have developed something that you would like to get included in the official tree, you have a few options for pushing patches back to phpMyAdmin. The preferred way is with a Github pull request.

[edit] Forking on Github

First you need to fork the phpMyAdmin's Git repository at https://github.com/phpmyadmin/phpmyadmin.

Then you can clone the forked repository to your computer (use the --reference parameter in case you already have a phpMyAdmin repository):

 git clone https://github.com/yourname/phpmyadmin.git --reference /existing/pma/repository

Now you are ready to make the changes you want and push them back to github:

 EDIT
 git commit -a
 git push

As last step open your fork on github.com and create a pull request; then wait until somebody reviews, comments or merges your changes :-).

[edit] Publishing branch

You can also choose another way to publish your git repository. Once you create the repository on the server, you should add it to your local working copy:

git remote add yourrepo git@example.com:phpmyadmin.git

As the cloned repository is empty at start, you need to create at least one branch there:

git checkout master
git push yourrepo master

If you get permission errors during push, you most likely forgot to assign yourself push privileges on the repository.

Now you can create a local tracking branch, where you will do your development:

git branch --track yourbranch yourrepo/master

You will do all your development in this branch, publishing it to the server time to time:

git push # while you have checkouted yourbranch

You should also regularly merge back the changes done in official repository:

git checkout yourbranch
git remote update origin # assuming official repository is called origin
git merge origin/master

[edit] Exporting patches

If you want to do a single change (or more separate patches), just do the changes, commit them (git commit) and use format-patch to generate patches for each commit:

git format-patch origin/master

The parameter which format-patch accepts is a reference to the starting point where your work started. It can be a commit hash, but usually you want the branch point where you separated from origin.

[edit] Merging remote branches

Once there is some other Git repository which you want to review and potentially merge, you can add it to your (already checked out, to share history) repository (first parameter is your name for that repository, you're free to choose anything):

git remote add other-repo https://github.com/other-repo/phpmyadmin.git

This just adds the reference to the repository. To see all the references you have in your repository:

git remote -v show

Now you need to fetch the content of this other repository (you need to do this also to fetch updates once the repository has been changed):

git remote update other-repo

Now you can access branches from that repository as other-repo/BRANCH_NAME so to checkout just call:

git checkout other-repo/master

To see what are recent changes in that repository in master branch just do:

git log other-repo/master

This lists full log includes all changes also those which you have seen in our repository. To see only the commits which are present in other-repo/master but not in origin/master:

git log origin/master..other-repo/master

This way you usually get just a few commits, which you can review using git show COMMIT_HASH. If you like these changes, just switch to master branch and merge them:

git checkout master
git merge other-repo/master

If you want to choose just one commit from an other branch, use:

git cherry-pick COMMIT_HASH

You can also merge all commits up to a certain revision; here, COMMIT_HASH is the latest revision you want:

git merge COMMIT_HASH

If you've just updated the remote repository, git shows you from which revision you have updated, eg:

git remote update pootle
Fetching pootle
remote: Counting objects: 1596, done.
remote: Compressing objects: 100% (1588/1588), done.
remote: Total 1588 (delta 1191), reused 0 (delta 0)
Receiving objects: 100% (1588/1588), 193.44 KiB | 161 KiB/s, done.
Resolving deltas: 100% (1191/1191), completed with 8 local objects.
From mort:/var/lib/vservers/web/var/lib/pootle/git/phpmyadmin
   bd722f1..a4d9137  master     -> pootle/master

You can use the revision to see what is new in the repository:

git log bd722f1..a4d9137

[edit] Changing history

As long as you have not published your changes, you can change your local history.

To add some changes to last commit (or simply to change a commit message) invoke following:

git commit --amend

If you have several commits and want to reorganize them, just invoke:

git rebase -i origin/master

And editor opens up, where you can reorder commits, squash several commits into one, change their commit messages and so on.

[edit] Merging translations

As it is usually not possible to merge po files across branches, Weblate does automatically propagate changes to all of them. Once translations are merge to each branch, you need to create merge commit to indicate that those changes are in both branches:

# switch to master branch
git checkout master
# check whether there are only translation changes in QA_4_0
git log ..origin/QA_4_0
# create merge commit
git merge -s ours origin/QA_4_0
# push changes
git push

In case there are mixed changes in maintenance (eg. QA_4_0) branch, you can merge individual commits with appropriate strategy.

For example, let's have following history, in QA_4_0 branch, which we want to merge to master (you can get this using git log --oneline ..origin/QA_4_0 ):

6c59e6e Code cleanup
d311135 Bug #3908 Calendar widget improperly redirects to home fixed
0d924a4 Merge remote-tracking branch 'origin/QA_4_0' into QA_4_0
ee13de7 Translated using Weblate (Welsh)
e27288c Translated using Weblate (Azerbaijani)
60db2bd Added spacing before  "{".
1bcb4a2 Changed coding style to the project coding style.

First we need to properly merge coding changes prior to po file updates:

git merge 60db2bd

Then tell Git it does not have to care about translation changes (0d924a4 is merge commit merging translations into QA_4_0):

git merge -s ours 0d924a4

And now finally merge rest of the changes:

git merge QA_4_0

And now we have branches properly merged, having all code changes in both of them.

[edit] Other documentation

There are also several free books available if you want to read more, I'd recommend http://progit.org/

Personal tools