Difference between revisions of "Git"

From Freephile Wiki
Jump to navigation Jump to search
(remove template)
(generic transcription of the post I did for work)
(33 intermediate revisions by 2 users not shown)
Line 1: Line 1:
The [[mw:Git (software)|Git]] system (http://git-scm.com/) was originally developed by Linus Torvalds as a distributed version control system to replace '''BitKeeper''' for the Linux Kernel project
+
The Git system (http://git-scm.com/) was originally developed by Linus Torvalds as a distributed version control system to replace BitKeeper for the Linux Kernel project
 
 
The bottom line is this: modern software development may take many "forms", but it usually boils down to [http://nvie.com/posts/a-successful-git-branching-model/ this].  Git enables such a branched workflow. That is why distributed version control in general, and git in particular, is the most widely adopted version control system for software development <ref>https://ianskerrett.wordpress.com/2014/06/23/eclipse-community-survey-2014-results/</ref>
 
 
 
See [[Git/hacks]] for example commands
 
  
 
== Intro to Git ==
 
== Intro to Git ==
  
Greg Rundlett setup git repository hosting services at the IIC (http://svn.iic.harvard.edu/gitweb/)
+
The IIC has a new git repository hosting service.<br />
 +
You can browse our git repositories at http://svn.iic.harvard.edu/gitweb/
  
 
Why do we have git?  Because [http://whygitisbetterthanx.com Git is better than X]  Now that we have the "My DVCS is better than your DVCS" argument out of the way, you can actually get some valuable insights from that website if you are interested in comparing Git with Mercurial, Bazaar, Subversion or Perforce.  If I had to single out one primary advantage of Git, it would be that it actually features branching and merging.
 
Why do we have git?  Because [http://whygitisbetterthanx.com Git is better than X]  Now that we have the "My DVCS is better than your DVCS" argument out of the way, you can actually get some valuable insights from that website if you are interested in comparing Git with Mercurial, Bazaar, Subversion or Perforce.  If I had to single out one primary advantage of Git, it would be that it actually features branching and merging.
  
Repo visibility is completely customizable, as are individual permissions to write to repos.  I've installed a system called gitosis to handle the privileges through a special git repository. It uses Public Key cryptography rather than granting SSH accounts to everyone.  This makes it really easy to do your work securely without even needing a password.  For the curious, the actual mechanics of gitosis are detailed at [http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way scie.nti.st]. Although that link may still work, there is also https://git-scm.com/book/en/v1/Git-on-the-Server-Gitosis.
+
Repo visibility is completely customizable, as are individual permissions to write to repos.  I've installed a system called gitosis to handle the privileges through a special git repository. It uses Public Key cryptography rather than granting SSH accounts to everyone.  This makes it really easy to do your work securely without even needing a password.  For the curious, the actual mechanics of gitosis are detailed at [http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way scie.nti.st]
  
 
{{Messagebox |
 
{{Messagebox |
Line 19: Line 16:
 
To host a public repo, go to http://github.com
 
To host a public repo, go to http://github.com
 
}}
 
}}
 +
== Tools ==
  
You might want to read about how we [[Git/migrating to git|migrate from Subversion to Git]] or how [http://julienrenaux.fr/2014/02/28/leading-the-svn-to-git-migration/ others have done it]
 
 
== Initial Configuration ==
 
In your [https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup first time setting up Git on a new computer], you want to configure your username and email among other settings.
 
<source lang="bash">
 
git config --global user.name "Greg Rundlett"
 
git config --global user.email greg@freephile.com
 
git config --global core.editor vim
 
git config --global diff.tool meld
 
git config --global --add color.ui true
 
# store password in memory for an hour
 
git config --global credential.helper 'cache --timeout=3600'
 
 
 
# recent packaged versions of git might be 1.8.3.1 (CentOS 7.4) whereas the current available is 2.15.1
 
# push.default is unset; its implicit value is changing in
 
# Git 2.0 from 'matching' to 'simple'. To squelch this message
 
# and adopt the new behavior now, use:
 
git config --global push.default simple
 
</source>
 
=== Example .gitconfig ===
 
<code>git config --global -e</code> and paste in the following:
 
<source lang="ini">
 
[user]
 
        name = Greg Rundlett
 
        email = greg@freephile.com
 
 
[alias]
 
        co = checkout
 
        ci = commit
 
        unstage = reset HEAD
 
        wu = log --stat origin..@{0}
 
        wup = log -p origin..@{0}
 
        lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative
 
 
[core]
 
        excludesfile = /home/greg/.gitignore_global
 
        editor = vim
 
 
[color]
 
        ui = true
 
 
[credential]
 
        helper = cache --timeout=3600
 
 
# ------------------ M E R G E -------------------------
 
[merge]
 
    tool = meld
 
 
[mergetool "meld"]
 
    cmd = meld --auto-merge \"$LOCAL\" \"$BASE\" \"$REMOTE\" --output \"$MERGED\" --label \"MERGE (REMOTE BASE MY)\"
 
    trustExitCode = false
 
 
[mergetool]
 
    # don't ask if we want to skip merge
 
    prompt = false
 
 
    # don't create backup *.orig files
 
    keepBackup = false
 
 
# ------------------ D I F F -------------------------
 
[diff]
 
    guitool = meld
 
 
[difftool "meld"]
 
    cmd = meld \"$LOCAL\" \"$REMOTE\" --label \"DIFF (Original v. Mine)\"
 
 
 
[push]
 
        default = simple
 
[gitreview]
 
        remote = origin
 
[help]
 
        format = web
 
[web]
 
#      browser = google-chrome
 
        browser = firefox
 
</source>
 
 
{{Highlight
 
|text = If you want to browse the git help in your browser (as above), then make sure you <code>sudo apt-get install git-doc</code> to get the HTML files}}
 
 
== Decentralized Workflow and Branching Model ==
 
Here's a good explanation on how most groups use Git in a successful branching model for development, "master", release branches, hotfixes, etc.
 
http://nvie.com/posts/a-successful-git-branching-model/
 
 
 
== Submodules ==
 
Using multiple repositories to compose your project.  See https://git-scm.com/book/en/v2/Git-Tools-Submodules
 
 
<source lang="bash">
 
git init myproject
 
cd myproject
 
git submodule add git@github.com:example.com/htdocs.git website
 
git submodule add https://gerrit.wikimedia.org/r/p/mediawiki/core.git mediawiki
 
git submodule add https://gitlab.com/Aranad/tools.git odtools
 
cd mediawiki/
 
git checkout REL1_31
 
cd ../
 
git commit -m 'initial commit'
 
git diff --submodule
 
git config --global diff.submodule log
 
git diff
 
git config -f .gitmodules submodule.mediawiki.branch REL1_31
 
git submodule update --remote
 
git status
 
git commit -am 'tracking REL1_31 in the mediawiki submodule'
 
git config status.submodulesummary 1
 
git log -p --submodule
 
cd mediawiki/
 
git submodule update --remote --merge
 
git config alias.sdiff '!'"git diff && git submodule foreach 'git diff'"
 
git config alias.spush 'push --recurse-submodules=on-demand'
 
git config alias.supdate 'submodule update --remote --merge'
 
</source>
 
 
== Tools ==
 
[[File:Meza.big.picture.pdf|thumb|Meza Big Picture|right]]
 
 
* http://git-scm.com/tools
 
* http://git-scm.com/tools
 
* http://github.com/guides/using-the-egit-eclipse-plugin-with-github
 
* http://github.com/guides/using-the-egit-eclipse-plugin-with-github
* [https://github.com/esc/git-big-picture Git Big Picture] is a nice visualization tool that produces images like the one on the right.
 
 
== Reporting ==
 
How many lines have I contributed since last year?
 
<source lang="bash">
 
git log --stat --author $(git config --get user.email) --since="last year" --until="last month" | awk -F',' '/files? changed/ {
 
    files += $1
 
    insertions += $2
 
    deletions += $3
 
    print
 
}
 
END {
 
    print "Files Changed: " files
 
    print "Insertions: " insertions
 
    print "Deletions: " deletions
 
    print "Lines changed: " insertions + deletions
 
 
}'
 
</source>
 
 
== Visualizing ==
 
There are a lot of ways to use the <code>git log</code> command to visualize your history. Everything from <code>git log --pretty=oneline</code> or <code>git log --graph --oneline</code> to <code>git log --graph --full-history --all --color --date=short --pretty=format:"%x1b[31m%h%x09%x1b[32m%d%x1b[0m%x20%ad %s"</code> which you probably want to put into your <code>~/.gitconfig</code> as some alias because who the heck is going to remember that one?<ref>https://stackoverflow.com/questions/1838873/visualizing-branch-topology-in-git</ref>  Of course there are also many GUI clients.
 
  
 
== Documentation ==
 
== Documentation ==
* http://wildlyinaccurate.com/a-hackers-guide-to-git Helpful intro because it doesn't pretend that Git is just like Subversion
 
 
* http://www.gitcasts.com GitCasts
 
* http://www.gitcasts.com GitCasts
 
* http://www.kernel.org/pub/software/scm/git/docs/everyday.html Everyday Git in 20 commands
 
* http://www.kernel.org/pub/software/scm/git/docs/everyday.html Everyday Git in 20 commands
 
* http://git-scm.com/course/svn.html Git crash course for SVN users
 
* http://git-scm.com/course/svn.html Git crash course for SVN users
* http://utsl.gen.nz/talks/git-svn/intro.html This intro for git-svn (a combination of git + svn) actually provides a lot of information and especially gives perspective if you've tried to use svk.
 
* http://git.or.cz/course/svn.html
 
 
* http://software.complete.org/software/wiki/site/GitGuide Git Guide (short) at Software Complete.org
 
* http://software.complete.org/software/wiki/site/GitGuide Git Guide (short) at Software Complete.org
* '''http://git-scm.com/book/en/v2'''
+
* http://book.git-scm.com/index.html
 
* http://git-scm.com/documentation
 
* http://git-scm.com/documentation
 
* http://www.kernel.org/pub/software/scm/git/docs/user-manual.html
 
* http://www.kernel.org/pub/software/scm/git/docs/user-manual.html
Line 177: Line 32:
 
* http://github.com/guides/providing-your-ssh-key
 
* http://github.com/guides/providing-your-ssh-key
  
=== Git and Subversion ===
+
== Now what? ==
* http://git-scm.com/book/en/Git-and-Other-Systems-Git-and-Subversion
 
* http://viget.com/extend/effectively-using-git-with-subversion
 
* http://trac.parrot.org/parrot/wiki/git-svn-tutorial
 
* http://flavio.castelli.name/2007/09/04/howto_use_git_with_svn/
 
 
 
 
 
== Background ==
 
 
I got into Git to make managing Drupal projects possible.  Now that we have a distributed VCS, we can actually collaborate in multiple ways (more than just a centralized model<ref>http://whygitisbetterthanx.com/#any-workflow</ref>), and we can work offline .  We can easily branch and merge.  We can pull in updates from the Drupal core maintainers.  We can pull in updates from the Drupal community (module maintainers).  We can track our own custom modules - especially if they are developed by more than one person.  We can branch, tag and deploy these combined sources to multiple instances (dev, staging, production) across multiple instances of Drupal (e.g. client projects that should share the exact same codebase) and have complete clarity on where each project stands regarding patches and security fixes or updates.  There have been several attempts in the Drupal community (credit to Moshe, Ben,<ref>http://drupal.org/node/197666</ref> Dries, et al.<ref>http://drupal.org/node/355154</ref>) to get this all working over the past year or so and I think we're finally seeing the tide turn in our favor.  Drupal may actually start to be "easy" to maintain and deploy.  Actually, the whole point is to BE up-to-date on all our projects.  This only happens when it is feasible.  Git makes it feasible.
 
I got into Git to make managing Drupal projects possible.  Now that we have a distributed VCS, we can actually collaborate in multiple ways (more than just a centralized model<ref>http://whygitisbetterthanx.com/#any-workflow</ref>), and we can work offline .  We can easily branch and merge.  We can pull in updates from the Drupal core maintainers.  We can pull in updates from the Drupal community (module maintainers).  We can track our own custom modules - especially if they are developed by more than one person.  We can branch, tag and deploy these combined sources to multiple instances (dev, staging, production) across multiple instances of Drupal (e.g. client projects that should share the exact same codebase) and have complete clarity on where each project stands regarding patches and security fixes or updates.  There have been several attempts in the Drupal community (credit to Moshe, Ben,<ref>http://drupal.org/node/197666</ref> Dries, et al.<ref>http://drupal.org/node/355154</ref>) to get this all working over the past year or so and I think we're finally seeing the tide turn in our favor.  Drupal may actually start to be "easy" to maintain and deploy.  Actually, the whole point is to BE up-to-date on all our projects.  This only happens when it is feasible.  Git makes it feasible.
 
* http://versioncontrolblog.com/2007/08/02/upgrading-drupal-52-with-git/
 
* http://versioncontrolblog.com/2007/08/02/upgrading-drupal-52-with-git/
Line 192: Line 40:
 
I pulled down the whole clone (which is only 26MB in size) of mikl's public history of Drupal in a few minutes.
 
I pulled down the whole clone (which is only 26MB in size) of mikl's public history of Drupal in a few minutes.
  
With Git, it is even possible to manage projects which are composites of multiple sources <ref>http://git.or.cz/gitwiki/GitSubmoduleTutorial</ref> (Ever tried that with Subversion's 'externals'? -- Don't bother to try it with Subversion because it just doesn't work!  Not only are externals feature poor, you'll still end up wanting to merge even more than before.  And as we know, merging is not a feature in Subversion.)
+
With Git is even possible to manage projects which are composites of multiple sources <ref>http://git.or.cz/gitwiki/GitSubmoduleTutorial</ref> (Ever tried that with Subversion's 'externals'? -- Don't bother to try it with Subversion because it just doesn't work!  Not only are externals feature poor, you'll still end up wanting to merge even more than before.  And as we know, merging is not a feature in Subversion.)
  
  
Line 215: Line 63:
 
Only in /var/www/drupal/sites: www.example.org
 
Only in /var/www/drupal/sites: www.example.org
 
</pre>
 
</pre>
 
+
== How it was done ==
== Git Repo Hosting ==
 
See [[Git repo hosting]]
 
 
 
== Building a Git server ==
 
 
 
(This recipe was from 2008.  It may still work, but ymmv)
 
  
 
Generally following the series of instructions at
 
Generally following the series of instructions at
 
http://vafer.org/blog/20080115011413  I installed Git-core, gitweb and gitosis on the  host
 
http://vafer.org/blog/20080115011413  I installed Git-core, gitweb and gitosis on the  host
<source lang="bash">
+
<pre>
 
# install git, the git-svn tool and the viewvc equivalent
 
# install git, the git-svn tool and the viewvc equivalent
 
apt-get install git-core git-svn gitweb
 
apt-get install git-core git-svn gitweb
Line 305: Line 147:
 
# and install it
 
# and install it
 
apt-get install gitosis
 
apt-get install gitosis
</source>
+
</pre>
 +
 
 +
== References ==
 +
<references />
  
  
Line 333: Line 178:
 
* http://www.davidgrant.ca/maintaining_vendor_sources_with_subversion
 
* http://www.davidgrant.ca/maintaining_vendor_sources_with_subversion
 
* http://www.burtonini.com/blog/computers/svn-vendor-2005-05-04-13-55
 
* http://www.burtonini.com/blog/computers/svn-vendor-2005-05-04-13-55
 
{{References}}
 
  
 
[[Category:Tools]]
 
[[Category:Tools]]
Line 343: Line 186:
 
[[Category:Howto]]
 
[[Category:Howto]]
 
[[Category:Subversion]]
 
[[Category:Subversion]]
[[Category:System Administration]]
+
[[Category:SystemAdministration]]

Revision as of 21:56, 21 April 2009

The Git system (http://git-scm.com/) was originally developed by Linus Torvalds as a distributed version control system to replace BitKeeper for the Linux Kernel project

Intro to Git[edit | edit source]

The IIC has a new git repository hosting service.
You can browse our git repositories at http://svn.iic.harvard.edu/gitweb/

Why do we have git? Because Git is better than X Now that we have the "My DVCS is better than your DVCS" argument out of the way, you can actually get some valuable insights from that website if you are interested in comparing Git with Mercurial, Bazaar, Subversion or Perforce. If I had to single out one primary advantage of Git, it would be that it actually features branching and merging.

Repo visibility is completely customizable, as are individual permissions to write to repos. I've installed a system called gitosis to handle the privileges through a special git repository. It uses Public Key cryptography rather than granting SSH accounts to everyone. This makes it really easy to do your work securely without even needing a password. For the curious, the actual mechanics of gitosis are detailed at scie.nti.st

You can actually host your own private repository on any server that you have access to. To collaborate with your peers, export a bare repo [1] and use SSH keys. more

To host a public repo, go to http://github.com

Tools[edit | edit source]

Documentation[edit | edit source]

Now what?[edit | edit source]

I got into Git to make managing Drupal projects possible. Now that we have a distributed VCS, we can actually collaborate in multiple ways (more than just a centralized model[2]), and we can work offline . We can easily branch and merge. We can pull in updates from the Drupal core maintainers. We can pull in updates from the Drupal community (module maintainers). We can track our own custom modules - especially if they are developed by more than one person. We can branch, tag and deploy these combined sources to multiple instances (dev, staging, production) across multiple instances of Drupal (e.g. client projects that should share the exact same codebase) and have complete clarity on where each project stands regarding patches and security fixes or updates. There have been several attempts in the Drupal community (credit to Moshe, Ben,[3] Dries, et al.[4]) to get this all working over the past year or so and I think we're finally seeing the tide turn in our favor. Drupal may actually start to be "easy" to maintain and deploy. Actually, the whole point is to BE up-to-date on all our projects. This only happens when it is feasible. Git makes it feasible.

I pulled down the whole clone (which is only 26MB in size) of mikl's public history of Drupal in a few minutes.

With Git is even possible to manage projects which are composites of multiple sources [5] (Ever tried that with Subversion's 'externals'? -- Don't bother to try it with Subversion because it just doesn't work! Not only are externals feature poor, you'll still end up wanting to merge even more than before. And as we know, merging is not a feature in Subversion.)


Comparisons of Branches, sources etc.[edit | edit source]

When comparing large trees of files, you need a good set of tools to be able to filter out noise. Normally KDiff3 is very good at this. However, KDiff3 is not available yet as a package for Ubuntu. If you compile it from source, I still found that the most important feature -- the preprocessor -- would not work if more than one command were piped together.

Specifically, I couldn't use this preprocessor setting which worked great for me in the past: sed "s/\$\(Id\|Revision\|Author\|Log\|Header\|Date\).*\$/\$\1\$/" | sed "s#/\* vim: set.*#/* vim: set ... */#" | sed "s/^.*opyright.*$/Copyright Greg Rundlett :-)/"

Without the benefit of a good preprocessor, KDiff would falsely tell me that there were 1,523 files which differed between DRUPAL-6-9 and DRUPAL-6-10

Kompare seemed hard to configure, and Meld didn't apply the pre-processor to directory compares. So, I used the command-line version of diff:
greg@greg-linux:~/work/git/drupal$ diff -r --exclude=.git --exclude=.svn --brief --ignore-matching-lines="$Id" . /var/www/drupal/

Only in /var/www/drupal/: favicon.ico
Only in /var/www/drupal/sites/all: modules
Only in /var/www/drupal/sites/all: themes
Only in /var/www/drupal/sites: dev.example.org
Only in /var/www/drupal/sites: example.org
Only in /var/www/drupal/sites: localhost
Only in /var/www/drupal/sites: prod.example.org
Only in /var/www/drupal/sites: www.example.org

How it was done[edit | edit source]

Generally following the series of instructions at http://vafer.org/blog/20080115011413 I installed Git-core, gitweb and gitosis on the host

# install git, the git-svn tool and the viewvc equivalent
apt-get install git-core git-svn gitweb

# run the git-daemon - a really simple server for git repositories
sudo -u git git-daemon --reuseaddr --verbose --base-path=/home/git/repositories/ --detach

# create a service that starts when the machine starts
cat > /etc/init.d/git-daemon << EOF
#!/bin/sh

test -f /usr/bin/git-daemon || exit 0

. /lib/lsb/init-functions

GITDAEMON_OPTIONS="--reuseaddr --verbose --base-path=/home/git/repositories/ --detach"

case "$1" in
start)  log_daemon_msg "Starting git-daemon"

start-stop-daemon --start -c git:git --quiet --background \
--exec /usr/bin/git-daemon -- ${GITDAEMON_OPTIONS}

log_end_msg $?
;;
stop)   log_daemon_msg "Stopping git-daemon"

start-stop-daemon --stop --quiet --name git-daemon

log_end_msg $?
;;
*)      log_action_msg "Usage: /etc/init.d/git-daemon {start|stop}"
exit 2
;;
esac
exit 0
EOF

# and add it to the various run-levels
update-rc.d git-daemon defaults

# setup the configuration of the gitweb repository browser
vi /etc/gitweb.conf

# Add cgi capabilities to our "Version Control" host
vi /etc/apache2/sites-available/git

# check the syntax of our apache configuration
apache2ctl configtest

# oops, the mod_rewrite isn't enabled
a2enmod rewrite

# check syntax and errors again
apache2ctl configtest

# restart apache
/etc/init.d/apache2 restart

# see what may have been added to the web docroot
ls /var/www/

# check to see that gitweb is installed
# and see what files it installs since they aren't in /var/www
dpkg --status gitweb
dpkg --listfiles gitweb

# create a symbolic link between the gitweb software and the repository root where we'll be viewing it.
ln -s /usr/share/gitweb /home/git/

# see what we have so far
ls /home/git/

# setup our gitweb configuration
vi /etc/gitweb.conf

# check if gitosis is packaged for ubuntu
apt-cache search gitosis
# and install it
apt-get install gitosis

References[edit | edit source]


Rant[edit | edit source]

quote 
After replacing the 1.0 code with 1.1 code, svn status will show files with local modifications as well as, perhaps, some unversioned files. If we did what we were supposed to do, the unversioned files are only those new files introduced in the 1.1 release of libcomplex--we run svn add on those to get them under version control. If the 1.1 code no longer has certain files that were in the 1.0 tree, it may be hard to notice them; you'd have to compare the two trees with some external tool and then svn delete any files present in 1.0 but not in 1.1. (Although it might also be just fine to let these same files live on in unused obscurity!) Finally, once our current working copy contains only the libcomplex 1.1 code, we commit the changes we made to get it looking that way. [1]

So, according to the official Subversion manual, the right way to track source code that you build on, you should

  1. download an export (they don't even consider that your vendor should be and IS using a VCS)
  2. add stuff that they added
  3. launch external tools to find out if there were deletions
  4. or just ignore deletions (tell me why we're using source code managment tools?)
  5. commit those changes

They admit that this is not exactly what you would like: "...things can quickly degrade into a situation where we have to manually re-create our customizations in the new version."

The official manual continues: "Vendor drops that contain more than a few deletes, additions, and moves complicate the process of upgrading to each successive version of the third-party data. So Subversion supplies the svn_load_dirs.pl script to assist with this process."

Except that svn_load_dirs.pl does not come with Subversion [2], and even if it did, it has limited or zero capabilities to handle and TRACK the status, history, and provenance of your source code. In any situation where a conflict arises, svn_load_dirs.pl will ask YOU to figure it out -- without any supporting details. Despite what the quote from the manual implies, the actual README with svn_load_dirs.pl says that it should NOT be used with sources that come from another VCS... those imports should be scripted ala cvs2svn etc.

I don't recommend looking at these, you'll just learn how NOT to do things. But here are examples of others who have needlessly fought with Subversion to manage their Drupal sites and source code

  • http://svnbook.red-bean.com/nightly/en/svn.advanced.vendorbr.html
  • svn_load_dirs.pl had licensing questions and was removed from the project. Now I guess it's back, in a contrib section, not in a default install. Anyway, a newer, better set of options exist named collectively vcs-load-dirs