User:Aude/Git

From mediawiki.org

Git[edit]

Clone[edit]

git clone ssh://aude@gerrit.wikimedia.org:29418/mediawiki/core.git mediawiki

Clone a specific tag or branch of a git repo:

git clone --branch 0.16.0 https://github.com/wikimedia/data-values-value-view.git

Checkout[edit]

Checkout version from a specific date or point in time:

git checkout `git rev-list -n 1 --before="2012-10-24 13:37" master`

or:

git checkout 'master@{2013-09-19 12:00:00}'

Config[edit]

Set global configuration, if only or primarily doing Wikimedia development:

git config --global user.name 'aude'
git config --global user.email 'my.email@gmail.com'

It is important for the email to match your email set in Gerrit, and the name is less important.

Set configuration for individual git repositories:

git config --local user.name 'aude'
git config --local user.email 'my.email@gmail.com'

View global config:

git config --global -l

View local config:

git config --local -l

If git or gerrit complain about the committer not matching, check the config, and you can also check how your commits are credited:

git log --format=full

General workflow[edit]

To commit stuff[edit]

git commit -a

This will bring up your text editor where you can enter a commit summary.

You can configure which text editor to use with the export command or add it to your ~/.bash_profile file.

export EDITOR=vim

or specify in git config:

git config --global core.editor "vim"

Using the text editor to provide more detailed commit summary is better, however it is also possible to provide the commit summary as an argument in the commit command:

git commit -a -m 'blah blah blah'

Add an empty directory:

Since git keeps track of files, a directory cannot be committed when it is entirely empty. A workaround is to add an empty .gitkeep file to the directory and then commit.

Stash[edit]

git stash save 'blah blah'

Update local code[edit]

in the morning, do:

git pull --rebase origin master

Submit code for review[edit]

Sanity check, make sure you are on the correct branch, etc.

git status
# On branch coolnewfeature
nothing to commit (working directory clean)

See what you are about to submit:

git show HEAD
commit e08067e92aa72d9bf5a740e1933469f4d249df96
Author: aude <my.email@gmail.com>
Date:   Sat Jan 5 17:25:33 2013 +0000

    add README
    
    Change-Id: I4ff31405425e27b974d44aabb78d5c3538db92cc
    
    Signed-off-by: aude <my.email@gmail.com>

Instead of git push origin, use git review to submit your change to gerrit:

git review

Branching[edit]

Make a local branch:

git checkout -b myfeature

Create a branch based on a commit hash:

If making a branch of a gerrit repo, be sure to use the merge commit hash and not the commit hash of the patch itself
git branch testbranch 35fcd4632057dc807665205a0df000e72c771937

Checkout a remote branch into a local branch:

git checkout -b Wikidata origin/Wikidata

Make some changes, commit them and push to review.

Create a new remote branch[edit]

git checkout -b mw1.21-wmf7 // local branch
git push gerrit mw1.21-wmf7 // push to gerrit

If needed, gerrit remote needs to be added:

git remote add gerrit ssh://aude@gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase.git

List branches[edit]

List remote branches:

git branch -r
  gerrit/0.1.x
  gerrit/0.2.x
  gerrit/master
  gerrit/mw1.21-wmf5
  gerrit/mw1.21-wmf6
  gerrit/wikidata-wmfphase1beta
  origin/0.1.x
  origin/0.2.x
  origin/HEAD -> origin/master
  origin/master
  origin/mw1.21-wmf5
  origin/mw1.21-wmf6
  origin/wikidata-wmfphase1beta

List all branches:

git branch -a
  mycoolfeature
  myothercoolstuff
  gerrit/0.1.x
  gerrit/0.2.x
  gerrit/master
  gerrit/mw1.21-wmf5
  gerrit/mw1.21-wmf6
  gerrit/wikidata-wmfphase1beta
  origin/0.1.x
  origin/0.2.x
  origin/HEAD -> origin/master
  origin/master
  origin/mw1.21-wmf5
  origin/mw1.21-wmf6
  origin/wikidata-wmfphase1beta

See current remote branches:

git remote -v

gerrit	ssh://aude@gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase.git (fetch)
gerrit	ssh://aude@gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase.git (push)
origin	https://gerrit.wikimedia.org/r/mediawiki/extensions/Wikibase.git (fetch)
origin	https://gerrit.wikimedia.org/r/mediawiki/extensions/Wikibase.git (push)

Get details for a remote:

git remote show gerrit
Enter passphrase for key '/home/aude/.ssh/gerrit': 
* remote gerrit
  Fetch URL: ssh://aude@gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase.git
  Push  URL: ssh://aude@gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase.git
  HEAD branch: master
  Remote branches:
    0.1.x                  tracked
    0.2.x                  tracked
    master                 tracked
    mw1.21-wmf5            tracked
    mw1.21-wmf6            tracked
    wikidata-wmfphase1beta tracked
  Local refs configured for 'git push':
    master                 pushes to master                 (local out of date)
    mw1.21-wmf5            pushes to mw1.21-wmf5            (local out of date)
    mw1.21-wmf6            pushes to mw1.21-wmf6            (up to date)
    wikidata-wmfphase1beta pushes to wikidata-wmfphase1beta (up to date)

Deleting branches[edit]

git branch -d myfeature

To batch delete (wildcard) branches:

git branch | grep review | xargs git branch -d

or to force delete branches with "not fully merged" stuff:

git branch | grep review | xargs git branch -D

To delete remote branches, such as on github, where one might have permission to do so:

git push github :sitelinkcomments

To batch delete remote branches:

git branch | grep review | xargs git push github --delete

Remove untracked files / clean[edit]

Removes directories and files:

git clean -df

Bash prompt[edit]

Display the git branch in the bash prompt, the following can be added to your ~/.bashrc file. To make the change take effect, then source ~/.bashrc

# view git branch in prompt                                                                         
function parse_git_branch {                                                                         
  git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'                      
}                                                                                                   
                                                                                                    
function proml {                                                                                    
  local LIGHT_GREEN="\[\033[1;32m\]"                                                                
  local   BOLDWHITE="\[\033[1;37m\]"                                                                
  local       WHITE="\[\033[;37m\]"                                                                 
                                                                                                    
PS1="$BOLDWHITE\h: $LIGHT_GREEN\$(parse_git_branch)\                                                
$WHITE $ "                                                                                          
}                                                                                                   
                                                                                                    
proml

When were the branches last modified?[edit]

See a list of all branches sorted by last modified date:

for k in `git branch | sed s/^..//`; do echo -e `git log -1 --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k --`\\t"$k";done | sort

Works on windows, mac or linux, but not as pretty:

git for-each-ref --sort=-committerdate refs/heads/

Tags[edit]

git tag 2013-05-22

git push gerrit 2013-05-22

Removing files from a repo[edit]

To recursively remove a folder and files from a repo:

git rm -rf wikipedia

Reset[edit]

git reset --hard HEAD

or

git checkout -- hello.php

To unstage files (e.g., after git add -A):

git reset --

View log[edit]

git log --oneline --decorate master origin/master

e5a04a3 (HEAD, master) Merge "Fix Sqlite upgrade test when profiling to database is enabled"
81d0388 [JobQueue] Increment stats for jobs ignored as duplicates.
e6f0bda Merge "Use Database::addQuotes instead of hardcoded quotes"
3066a50 Merge "Partial normalisation of hooks.txt"
6bd45d0 Merge "recentchanges.rc_ip is used for retroactive autoblocks"
a6a5ed4 Merge "Made the profilers that output text not break js."
ce4c01e Merge "Localisation updates from http://translatewiki.net."
0458ce3 Made the profilers that output text not break js.

Just a plain git log, with details:

git log

commit e5a04a3f54b1120de34e2627a27f116ab060de9c (HEAD, master)
Merge: 81d0388 fa4196b
Author: jenkins-bot <jenkins--@gerrit.wikimedia.org>
Date:   Fri Jan 4 23:23:20 2013 +0000

    Merge "Fix Sqlite upgrade test when profiling to database is enabled"

commit 81d03884cbbe00055db7ab0327919d1d6173d8b0
Author: Aaron Schulz <-----@wikimedia.org>
Date:   Thu Dec 20 16:38:36 2012 -0800

    [JobQueue] Increment stats for jobs ignored as duplicates.
    
    Change-Id: If4130f4eb79dc2d55b50a7adebfca43620a36d2c

commit e6f0bdadb50eb86a87e3f6567f444ba54de4dfb6
Merge: 3066a50 26f13ec
Author: IAlex <ialex.wiki@gmail.com>
Date:   Fri Jan 4 21:58:39 2013 +0000

    Merge "Use Database::addQuotes instead of hardcoded quotes"

Search commit messages[edit]

git log --grep='DEPLOY'

git log --grep='bug'

Patches[edit]

Create a patch[edit]

From the master branch:

git checkout -b coolnewfeature

make a bunch of changes

# to add everything with the * or you can add specific files
git add * 
git commit -m 'made changes'

# patch is a diff between coolnewfeature branch and master
# saved to a file: coolfeature.patch
git format-patch master --stdout > ~/coolfeature.patch

Apply the patch[edit]

# Check the patch first
git apply --stat ~/coolfeature.patch

# See if it can be applied cleanly
git apply --check ~/coolfeature.patch

# Apply the patch
git am --signoff < ~/coolfeature.patch

Revert[edit]

Revert a specific commit:

git revert fe80633d66218b37fc65dfe3f0aa61603dbb7ad2

Revert a merge commit (with -m 1 or -m 2 depending on which parent branch to revert back to):

git revert -m 1 6a8e942880d201e78f85ab7c572306e18c37bc4e

Amending[edit]

Amend specific commit in series of patches[edit]

git rebase -i HEAD~2

In interactive mode, then:

edit 7d20863 Introduce ChangeLineFormatter in the client                                            
pick de3e6a7 Split ChangeHandler::getPagesToUpdate into new class with tests

Then make changes, and then:

git add ChangeLineFormatterTest.php
git rebase --continue

Squash a commit[edit]

git rebase -i HEAD~2

In interactive mode, then:

pick 7d20863 Introduce ChangeLineFormatter in the client                                            
squash de3e6a7 Split ChangeHandler::getPagesToUpdate into new class with tests

Edit the commit message, then save and then git will combine the two commits into a single commit.

If amending and resubmitting to gerrit, then git review -R.

Amend author name[edit]

git commit --amend --author="New Author Name <email@address.com>"

Merge conflicts[edit]

git mergetool --tool=/path/to/tool

or set it:

git config --global mergetool.<tool>.path (FileMerge for Mac, kdiff3 for Linux)

Merge in subsequent commits into a patch[edit]

git review -d 16749
git rebase master
git add client/include/LangLinkHandler.php
git rebase --continue

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

View diffs[edit]

git diff HEAD~1 -- Wikibase.php

Submodules[edit]

Go get some coffee or tea while cloning core and updating submodules.

Checkout wmf core branch and extension submodules:

git clone ssh://aude@gerrit.wikimedia.org:29418/mediawiki/core.git
git checkout -b 1.21wmf7 origin/wmf/1.21wmf7
git submodule update --init

If renaming the core directory, references to the submodules need to be updated.

In core/extensions:

find . -name .git -exec sed -i 's/php-1.21wmf6/wikibase-repo/g' '{}' \;

in core/.git:

find . -type f -exec sed -i 's/php-1.21wmf6/wikibase-repo/g' '{}' \;
Removing submodules
See also

Split subpath[edit]

To split subdirectories of a git repo into separate repos:

Create clone copies and then in the clone:

git filter-branch --prune-empty --subdirectory-filter ValueView master

Git blame and credits[edit]

Get number of commits per author for a file:

git shortlog -sn Parser.php

Get number of lines per author, based on git blame:

git ls-tree -r --name-only -z HEAD includes/parser/Parser.php | xargs -0 -n1 git blame --line-porcelain HEAD | grep "^author " | sort | uniq -c | sort -nr

Number of commits by author:

git shortlog -sne

Gerrit[edit]

Get a list of projects[edit]

In the shell:

ssh -p 29418 -l aude gerrit.wikimedia.org gerrit ls-projects

Or go to https://gerrit.wikimedia.org/r/#/admin/projects/

Improving a patch[edit]

git review -d <CHANGE NUMBER>

make some changes

git add some/dir/file.txt
git commit --amend
git review -R

Adding a dependency[edit]

If you need to amend your patch to have the correct dependency:

git branch # Take note of the review/* branch that was created for this, it has an "*" in front of it
git checkout bug/1234 # Check out the local topic branch of your change
git rebase review/john/7000 # The branch name of the gerrit change we checked out earlier
  1. Resolve conflicts if needed,
  2. - use "git status" to see the files that need resolution
  3. - after fixing it in your editor, "git add filename" for each of the fixed files
git commit --amend -c HEAD # Re-commit your patch replacing the one with the wrong parent


git log -n5 --decorate --pretty=oneline # Verify that the last 5 entries of the log now start with:

# * (HEAD, bug/1234) your change
# * (review/john/700) the dependency
# * (gerrit/master)
git push gerrit HEAD:refs/for/master # Use this instead of `git review`

The git push directly will make sure that the dependency is kept and the other revisions that are already in gerrit will not be re-submitted.

Fix a dependency[edit]

git rebase -i gerrit/master

Change a commit to a new patchset, such as [1] 5a05e0e (5a05e0ef437278eff23c5a8b076b91f0cc7541c8) to cbcd5a0 (cbcd5a08c895d038a3ca7dc10e8d94806e2cae10).

Re-commit your patch replacing the one with the wrong parent

git commit --amend -c HEAD

Resubmit to gerrit:

git review -R

Import github repo into existing empty gerrit repo[edit]

Keyboard shortcuts[edit]

Gerrit has keyboard shortcuts. A list of shortcuts can be displayed by clicking "?".

Pre-commit checks[edit]

find . -name "*.php" -print0 | xargs -0 -n1 -P8 php -l

Deployment stuff[edit]

Each deployment, if extensions not at master
For new extensions

See also[edit]

External links[edit]

Shortcuts
  • [2] (unreviewed Wikibase patches)
Gerrit stuff
General