Difference between revisions of "Git"

From WhyAskWhy.org Wiki
Jump to: navigation, search
m (Trimmed content now that I'm pretty sure running 'git fetch' is safe (i.e., won't modify local content until it is merged in))
m (Reworked headings to remove what felt like a pointless top level heading for "questions")
Line 3: Line 3:
 
[[Category:Software]]
 
[[Category:Software]]
  
My scratch notes on Git. Someday this page may actually be useful.
+
My scratch notes on Git. Someday this page may actually be useful.  
  
== Questions ==
+
== How to retrieve the hash for the current revision in your git repo? ==
 
 
By answering these questions, I'll have a "cheat sheet" of useful tips/tricks to consult in the future.
 
 
 
 
 
=== How to retrieve the hash for the current revision in your git repo? ===
 
  
 
This is probably a poorly worded question, but essentially if you have cloned a repo and are trying to:
 
This is probably a poorly worded question, but essentially if you have cloned a repo and are trying to:
Line 87: Line 82:
  
  
=== How can you tell what branch or tag your working copy is on? ===
+
== How can you tell what branch or tag your working copy is on? ==
  
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
Line 100: Line 95:
  
  
=== How can you display available branches? ===
+
== How can you display available branches? ==
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 116: Line 111:
  
  
=== How do you display available tags? ===
+
== How do you display available tags? ==
  
 
<syntaxhighlight lang="bash" enclose="none">
 
<syntaxhighlight lang="bash" enclose="none">
Line 123: Line 118:
  
  
=== What if you are not seeing a tag that you know is available? ===
+
== What if you are not seeing a tag that you know is available? ==
  
 
For example I had a copy of the MediaWiki 1.19.1 tag checked out <ref name="svn-term" /> and even though a 1.19.2 tag was available I didn't see it when running <code>git tag -l</code>.  
 
For example I had a copy of the MediaWiki 1.19.1 tag checked out <ref name="svn-term" /> and even though a 1.19.2 tag was available I didn't see it when running <code>git tag -l</code>.  
Line 148: Line 143:
  
  
=== How do you display all recent changes (in short format)? ===
+
== How do you display all recent changes (in short format)? ==
  
==== Short version ====
+
=== Short version ===
  
 
We need to do three things:
 
We need to do three things:
Line 158: Line 153:
 
# Run <syntaxhighlight lang="bash" enclose="none">git log CURRENT_REV..HEAD --oneline</syntaxhighlight>
 
# Run <syntaxhighlight lang="bash" enclose="none">git log CURRENT_REV..HEAD --oneline</syntaxhighlight>
  
==== Real example ====
+
=== Real example ===
  
 
Our case:
 
Our case:
Line 202: Line 197:
 
</pre>
 
</pre>
  
=== How do you switch from one tag or branch to another? ===
+
== How do you switch from one tag or branch to another? ==
  
 
Using our earlier example, let's switch from the <code>1.19.1</code> tag to the <code>1.19.2</code> tag.
 
Using our earlier example, let's switch from the <code>1.19.1</code> tag to the <code>1.19.2</code> tag.
Line 218: Line 213:
  
  
=== How do you reset all changes after the last commit ? ===
+
== How do you reset all changes after the last commit ? ==
  
 
In other words, ''What is the Git equivalent of <syntaxhighlight lang="bash" enclose="none">svn revert -R .</syntaxhighlight>?''
 
In other words, ''What is the Git equivalent of <syntaxhighlight lang="bash" enclose="none">svn revert -R .</syntaxhighlight>?''
Line 241: Line 236:
  
  
=== How do you create a Git repository and prep it for sharing via HTTP? ===
+
== How do you create a Git repository and prep it for sharing via HTTP? ==
  
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
Line 254: Line 249:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=== What if you wanted that Git repository to be a clone of another repository? ===
+
== What if you wanted that Git repository to be a clone of another repository? ==
  
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
Line 267: Line 262:
  
  
=== How do you share a Git repository via HTTP? ===
+
== How do you share a Git repository via HTTP? ==
  
 
Several different web servers could be used for this, but here is an example using Apache 2.2.x. I've tried to make it pretty bare so it could apply the widest possible setups. For my setup I use a local LDAP server (same box as web server) instead of a password file. I feel this helps with user account/password management.
 
Several different web servers could be used for this, but here is an example using Apache 2.2.x. I've tried to make it pretty bare so it could apply the widest possible setups. For my setup I use a local LDAP server (same box as web server) instead of a password file. I feel this helps with user account/password management.

Revision as of 01:46, 27 September 2015


My scratch notes on Git. Someday this page may actually be useful.

How to retrieve the hash for the current revision in your git repo?

This is probably a poorly worded question, but essentially if you have cloned a repo and are trying to:

  1. Note the current revision/hash
  2. Upgrade to the latest version

I have this habit when upgrading extensions for MediaWiki as I like to document what changes have been made so I can have a starting point for troubleshooting odd behavior that shows up.

So far I've found that all of these work, just with varying degrees of feedback/change required [1]:

  • git show
    
    • This gives the most information, ranging from a colorized diff of the last commit, the last commit log and the colorized commit hash.
    • Use git show --oneline for an even shorter format (but without detailed log entry for the commit)
  • git rev-parse HEAD
    
    • This gives just the commit hash, but it is probably the best approach for automated work.
  • git pull
    

I've also found that when you run git pull (in an existing repo of course) that the commit hashes (short notation) will be shown and can be used with git log to see the changelog for the revision you just had up to the revision you have now.

Example of the output from upgrading the Interwiki MediaWiki extension from commit 9e79d4b213000035ac72817cdaaa6541412ef811 to commit 5510cd9b322becb9cb66a1a4080ddfe5ba78a47f:

cd /var/www/example.org/mediawiki/extensions/interwiki
git pull
remote: Counting objects: 60, done
remote: Finding sources: 100% (56/56)
remote: Getting sizes: 100% (8/8)
remote: Compressing objects: 100% (4/4)
remote: Total 56 (delta 34), reused 52 (delta 34)
Unpacking objects: 100% (56/56), done.
From https://gerrit.wikimedia.org/r/p/mediawiki/extensions/Interwiki
   9e79d4b..5510cd9  master     -> origin/master
Updating 9e79d4b..5510cd9
Fast-forward
 Interwiki.alias.php |    4 +-
 Interwiki.i18n.php  |   73 +++++++++++++++++++++++++++++++++++++++++---------
 Interwiki_body.php  |   19 ++++++++++---
 3 files changed, 76 insertions(+), 20 deletions(-)

This line lists the short version of the commit hashes:

Updating 9e79d4b..5510cd9

and as mentioned previously, you can use the two as shown here to get the changelog between the two commits:

git log 9e79d4b..5510cd9

Only showing a snippet, but it includes the next in the series (not the entry for 9e79d4b itself) and the last. The ... indicates the portion I cut out.

commit 5510cd9b322becb9cb66a1a4080ddfe5ba78a47f
Author: Translation updater bot <l10n-bot@translatewiki.net>
Date:   Tue Oct 2 13:46:02 2012 +0000

    Localisation updates from http://translatewiki.net.

    Change-Id: I01fc03d8cbf6731e01a5cd2c6effb80cc47dc4ff

...

commit f32b40b2b89cf3c38d8e6b3d9a5c01599acba079
Author: Siebrand Mazeland <s.mazeland@xs4all.nl>
Date:   Thu Aug 30 14:57:43 2012 +0200

    Replace deprecated User::editToken with User::getEditToken

    Change-Id: I3382a27ee788eb5dc6b7b033987326ce1ab1dc91


How can you tell what branch or tag your working copy is on?

cd /my/git/branch/or/tag/
git describe --tags

The command finds the most recent tag that is reachable from a commit. If the tag points to the commit, then only the tag is shown. Otherwise, it suffixes the tag name with the number of additional commits on top of the tagged object and the abbreviated object name of the most recent commit.

By default (without --all or --tags) git describe only shows annotated tags.[2][3]


How can you display available branches?

git branch
Local
git branch
Remote
git branch -r
All
git branch -a


How do you display available tags?

git tag -l | sort -V


What if you are not seeing a tag that you know is available?

For example I had a copy of the MediaWiki 1.19.1 tag checked out [4] and even though a 1.19.2 tag was available I didn't see it when running git tag -l.

Running git fetch [5] seemed to do the trick:

remote: Counting objects: 96, done
remote: Finding sources: 100% (49/49)
remote: Getting sizes: 100% (58/58)
remote: Compressing objects: 100% (11/11)
remote: Total 49 (delta 30), reused 36 (delta 28)
Unpacking objects: 100% (49/49), done.
From https://gerrit.wikimedia.org/r/p/mediawiki/core
   49857f8..f25ee70  REL1_19    -> origin/REL1_19
   566852d..944e196  master     -> origin/master
 * [new tag]         1.19.2     -> 1.19.2


How do you display all recent changes (in short format)?

Short version

We need to do three things:

  1. Determine the current revision of our repo
  2. Obtain recent changes
  3. Run git log CURRENT_REV..HEAD --oneline

Real example

Our case:

  • Our local clone is at /opt/HttpUploadComponent
  • The current branch for that clone is master
  • There are no other branches or tags in the remote repository

With those details known, determining the current revision of our repo is easy:

  1. $ cd /opt/HttpUploadComponent
  2. $ git show --oneline
b7f8d3f Merge pull request #38 from QuentinC/master

With our current revision known (b7f8d3f), we can ask git for the changes between our revision and the latest (known as HEAD) by running git log b7f8d3f..HEAD. Before that command will work however we need to pull in the remote history so git has access to the commit log entries.

  1. $ git fetch
  2. $ git log b7f8d3f..HEAD --oneline
c0d2383 Merge pull request #54 from SamWhited/use_python3_virtualenv
0064cc0 Use pyvenv instead of virtualenv
d421ace use python3
8a29322 strip non ascii chars from filenames. use base64 encoding for directories
9c0ebce Merge branch 'master' of github.com:siacs/HttpUploadComponent
6f458de explicitly use python3
6e0208b Merge pull request #49 from SamWhited/tests
40f2d23 Restructure project for building a package
b1bbdd9 Merge branch 'master' of github.com:siacs/HttpUploadComponent
934c6e4 use namespace from XEP
bed68b3 update readme
0b27678 modified readme to point to xep and added reference to the gajim plugin
2011440 added license file. fixes #48
5f04e75 added user and full path to service file
6fb0b86 removed python 2 compat because its causing trouble
76678c3 Merge pull request #43 from moparisthebest/master
f6796f6 Merge pull request #45 from sezuan/allow_web_clients
5f35a0b Merge pull request #50 from weiss/nginx-max-body-size
9a892e3 nginx_site_example: Specify client_max_body_size
fd59a7f answer OPTIONS requests to allow web clients to upload files
c82f00c Add support for uploading/downloading to/from subdirectories

How do you switch from one tag or branch to another?

Using our earlier example, let's switch from the 1.19.1 tag to the 1.19.2 tag.

git checkout 1.19.2

Previous HEAD position was d0c0aab... Merge "Bump $wgVersion and add release-notes for 1.19.1" into REL1_19
HEAD is now at f25ee70... Release notes and increment version

The same approach works for switching between branches.


How do you reset all changes after the last commit ?

In other words, What is the Git equivalent of svn revert -R .?

Reset all changes [6]:

git reset HEAD --hard

then clean out everything untracked (temp files, test changes, etc):

git clean -fd

Optionally you may want to include the -x option as well to prune ignored files:

git clean -fdx


How do you create a Git repository and prep it for sharing via HTTP?

mkdir /var/www/git/repos/project.git
cd /var/www/git/repos/project.git
git --bare init
chown -R www-data:www-data /var/www/git/repos/project.git
sudo -u www-data 
git update-server-info
cd /var/www/git/repos/project.git
mv hooks/post-update.sample hooks/post-update

What if you wanted that Git repository to be a clone of another repository?

git clone --mirror <remote repository>

or

git clone --mirror /work/repo


How do you share a Git repository via HTTP?

Several different web servers could be used for this, but here is an example using Apache 2.2.x. I've tried to make it pretty bare so it could apply the widest possible setups. For my setup I use a local LDAP server (same box as web server) instead of a password file. I feel this helps with user account/password management.

Note: For the SSL portion, the SSLCipherSuite directive may need a closer look as I have had that value in a conf file for several years and there may be a better approach to use.

##################################################################
# vhost settings for git.example.org
##################################################################

<VirtualHost *:8080>
    DirectoryIndex index.html
    UseCanonicalName off

    ServerName git.example.org
    ServerAdmin webmaster@example.org

    DocumentRoot /var/www/example.org/git

    # Enable SSL for this vhost
    SSLEngine on

    # Path to certificate and key
    SSLCertificateFile   /etc/ssl/mycerts/wildcard.example.org_server.crt

    # Should be kept where only root can get to it.
    SSLCertificateKeyFile /etc/ssl/private/wildcard.example.org_server.key

    # allow all ciphers for the initial handshake,
    # so export browsers can upgrade via SGC facility ...
    SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL

    <Location />
         SSLOptions +StrictRequire

         # REQUIRE SSL for all connections
         # http://httpd.apache.org/docs/2.1/mod/mod_ssl.html#sslrequiressl
         SSLRequireSSL

         # ... but finally deny all browsers which haven't upgraded
         SSLRequire %{SSL_CIPHER_USEKEYSIZE} >= 128
    </Location>

#########################################################
# misc git repos
#########################################################

    Alias /repos /var/www/git/repos
    <Location /repos>
        DAV on
        Options ExecCGI FollowSymLinks Indexes

        #####################################
        # Apache auth options
        #####################################

        Satisfy All
        AuthUserFile /usr/local/apache/access/git-repos.htpasswd
        Require valid-user

    </Location>

    # The goal is to apply the CGI options to any git repo's hooks dir
    # under /var/www/git/repos
    <DirectoryMatch "^/var/www/git/repos/.+/hooks/.+">
        SetHandler cgi-script
        Options +ExecCGI
    </DirectoryMatch>
</VirtualHost>


References

Manual Pages

git fetch


Sharing a Git repository via HTTP(s)


Unsorted links

These are just Git related links that I've dumped from my bookmarks folder. I'll go back and prune duplicates.