Table of Contents
Using git
Possible Workflows
It is important that we adopt a workflow to use with git - otherwise branching and merging will be disorganized. This is important to allow distributed/concurrent work on features, releases, etc.
There seem to be a number of options out there - documented in varying levels of detail on the web.
gitflow seems to be a fairly established workflow, Scott Chacon (a developer at github, and writer of Pro Git) for example, criticises gitflow as being over-complicated (and the gitflow scripts are only usable on the command-line).
I think gitflow provides a good starting point however, and we could modify the exact branching structure as required.
gitflow explained: http://nvie.com/posts/a-successful-git-branching-model/
Scott Chacon's counter-view: http://scottchacon.com/2011/08/31/github-flow.html
Though I like the idea of deploying often - I don't think we are likely to reach the 'agility' of Scott's deploying every few hours [DISCUSS!], so I'm more drawn to the gitflow organization. I do agree with Scott that all branches should be pushed to origin - it seems silly not to make individuals' or teams' branches available to all. Managed correctly, they will not interfere with the main deployable code.
Branch names should be meaningful (adopting conventions as appropriate) - for sure.
Pull requests for internal code reviews need to be examined further…
Both appear to agree not to work directly on the deployable branch ('master'), and Scott suggests that merging to master should only take place following a 'pull request' code review.
Other options:
Branch-per-feature: http://dymitruk.com/blog/2012/02/05/branch-per-feature/ This appears to be pretty much what Scott Chacon is advocating. [REVIEW]
Git Book workflows: http://git-scm.com/book/ch3-4.html [REVIEW] (Also http://git-scm.com/book/ch5-2.html [REVIEW])
Misc:
http://www.lullabot.com/articles/git-best-practices-workflow-guidelines [REVIEW]
http://reinh.com/blog/2009/03/02/a-git-workflow-for-agile-teams.html [REVIEW]
http://jk.gs/gitworkflows.html [REVIEW]
Pull Requests
Automation - Continuous Integration and Deployments, Etc.
[TODO]
Hosting
Should we be hosting git ourselves - or have it hosted elsewhere? If so, where?
I think most workflow models agree that, despite the benefits of working with distributed repositories, a central 'origin' repo is needed/desirable [CLARIFY]. Individual team members can work with their own repo - sharing between themselves if necessary (though if working with many distinct feature-type branches, and committing and pushing these branches often - this peer-to-peer sharing shouldn't be necessary).
(We would need to consider whether we would want to prevent history re-writing in this central repo.)
So where would we host this central repo? In particular, do we want to have to provision, set-up, and maintain a server to provide this repo? Answer is probably no.
There are a number of hosted services available - with the frontrunners probably being gitHub and BitBucket. GitHub, I think, is the original git hosting solution - and hosts many open source projects. BitBucket appears to be trying to rival GitHub, and I have found it useful for private projects (which GitHub won't host for free). This reflects differences in their pricing model.
I think it is pointless agonizing too much over our choice, simple due diligence and a team straw-poll should suffice - as it should be pretty straightforward to clone repos and migrate from one provider to another (though this may be a pain).
We will have backups of our repositories on every developer PC, and if we are really paranoid (or cautious?) we can keep cloned and regularly updated versions of the repos on a Wiley server somewhere (Oxford?) - updated by cron script.
Both GitHub and BitBucket have enterprise offerings that allow you to run their software inside your firewall - but for our set-up I can't see the benefit of this.
Assuming we are a fairly static team size (though I don't know how many outsourced developers will need access), and we may wish to create any number of private repos - then I believe the BitBucket pricing is better.
Basics
Git book: http://git-scm.com/book
[TODO]
Feature Branch: Create, Commit, Merge, Delete
Create Feature Branch, Commit:
$ git checkout -b feature-001 master $ vi file123 $ git commit -a $ git push origin feature-001
Merge, Delete, Push:
$ git checkout master $ git merge --no-ff feature-001 $ git push origin master $ git branch -d feature-001 $ git push origin :feature-001 # this deletes the feature branch on origin
In Eclipse, it is possible to import (clone) a project from Git - and then a new feature branch can be created using the 'switch to' function (Team → Switch To → New Branch…). Commits can be made against the new branch and pushed as normal.
Ah! Issue: Cannot merge with no fast-forward in eGit yet. See links below…
http://stackoverflow.com/questions/11628493/egit-how-to-prevent-fast-forward-merge
Moving to a New Repo
If you have started working in one repo, but then need to move elsewhere:
1. Create new empty repo in new location (this may vary but if creating directly from command-line):
$ cd /apps/git/dotcms/wdp/modules/ $ mkdir jhpplugin.git $ cd jhpplugin.git/ $ git init --bare
2. Change remote location on your local machine and then push to new location (ensure you've got the latest changes from your old location first, of course):
$ git remote -v origin ssh://[email protected]/cwsadmin/jhpplugin.git (fetch) origin ssh://[email protected]/cwsadmin/jhpplugin.git (push) $ git remote set-url origin ssh://[email protected]/apps/git/dotcms/wdp/modules/jhpplugin.git $ git remote -v origin ssh://[email protected]/apps/git/dotcms/wdp/modules/jhpplugin.git (fetch) origin ssh://[email protected]/apps/git/dotcms/wdp/modules/jhpplugin.git (push) $ git push -u origin --all $ git push -u origin --tags
2b. If you haven't pushed from this repo before - you can use
$ git remote add origin ssh://[email protected]/apps/to/project.git
Job done. Now remember to tell everyone to use the new location ;)
3. Moving existing local copies:
$ git remote -v origin [email protected]:cwsadmin/jhpplugin.git (fetch) origin [email protected]:cwsadmin/jhpplugin.git (push) $ git remote set-url origin ssh://[email protected]/apps/git/dotcms/wdp/modules/jhpplugin.git $ git remote -v origin ssh://[email protected]/apps/git/dotcms/wdp/modules/jhpplugin.git (fetch) origin ssh://[email protected]/apps/git/dotcms/wdp/modules/jhpplugin.git (push)
4. Linking to new remote repo:
$ cd /path/to/my/repo $ git remote add origin [email protected]:alunwcom/dummy.git $ git push -u origin --all # pushes up the repo and its refs for the first time $ git push -u origin --tags # pushes up any tags
Misc.
Adding Useful Aliases
31-Jan-2022: Work laptop aliases:
[alias] co = checkout st = status lg = log --graph --all --pretty=format:'%C(red)%h%C(reset) %C(yellow)%d%Creset %s %Cgreen(%cd)%Creset' --abbrev-commit -- lgc = log --graph --pretty=format:'%C(red)%h%C(reset) %C(blue)%cN%C(reset):%C(yellow)%d%Creset %s %Cgreen(%cd, %cr)%Creset' --abbrev-commit -- lgf = log --graph --all --pretty=format:'%C(red)%h%C(reset) %C(blue)%cN%C(reset):%C(yellow)%d%Creset %s %Cgreen(%cd, %cr)%Creset' --abbrev-commit --
Currently adding short status alias, and pretty log alias:
$ git config --global alias.st status #$ git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)%Creset' --abbrev-commit --" $ git config --global alias.lg "log --graph --pretty=format:'%C(red)%h%C(reset) %C(blue)%cN%C(reset):%C(yellow)%d%Creset %s %Cgreen(%cd, %cr)%Creset' --abbrev-commit --"
Other options…
$ git config –global alias.lg “log –graph –pretty=format:'%Cred%h [%cn]%Creset - %s %C(bold blue) (%ci)%Creset' –abbrev-commit –”
$ git config --global --unset alias.lg
BitBucket SSH issue on Linux
I've experienced this error when working with BitBucket on Centos6:
$ git clone https://[email protected]/alunwcom/git-test.git Initialized empty Git repository in /home/jtadmin/git-test/.git/ (gnome-ssh-askpass:4391): Gtk-WARNING **: cannot open display:
The problem is that I am running the command in a Putty session, while an environment variable (SSH_ASKPASS) is specifying a Gnome dialog:
$ echo $SSH_ASKPASS /usr/libexec/openssh/gnome-ssh-askpass
This can be unset temporarily, or updated in .bash_profile (note that .bash_profile doesn't run when opening the 'screen' command).
GitHub CLI Cloning
The gotcha here is that although the GitHub front-end shows the https repository URL as being read+write access - this isn't actually the case. You need SSH access in order to write. Or you get this error:
$ git push origin master error: The requested URL returned error: 403 while accessing https://github.com/alunwcom/git-repo-test.git/info/refs fatal: HTTP request failed
If you've just cloned the repository using the HTTPS URL, this means editing the remote URL:
$ git clone https://github.com/alunwcom/git-repo-test.git ... $ git remote -v origin https://github.com/alunwcom/git-repo-test.git (fetch) origin https://github.com/alunwcom/git-repo-test.git (push) $ git remote set-url origin ssh://[email protected]/alunwcom/git-repo-test.git
NOTE: You will have also had to set-up SSH public key access or you will hit this error:
$ git push origin master Permission denied (publickey). fatal: The remote end hung up unexpectedly
Generating keys for GitHub is covered here: https://help.github.com/articles/generating-ssh-keys
This is a brief version:
$ ssh-keygen -t rsa -C "[email protected]" ... Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/jtadmin/.ssh/id_rsa. Your public key has been saved in /home/jtadmin/.ssh/id_rsa.pub. ... $ cat ~/.ssh/id_rsa.pub # copy output to clipboard, so it can be pasted into GitHub form ...
NOTE: If you already have a public key generated, you will be prompted to overwrite it if you generate a new key.
The public key can then be added to GitHub here: https://github.com/settings/ssh
Forking
[TODO]
Fork in GitHub or BitBucket.
Clone your forked repo locally to work on.
Add an extra upstream remote repo pointing to the original forked repo (so you can get updates to the original repo):
$ git remote -v origin ssh://[email protected]/alunwcom/dotCMS.git (fetch) origin ssh://[email protected]/alunwcom/dotCMS.git (push) $ git remote add upstream https://github.com/dotCMS/dotCMS.git $ git remote -v origin ssh://[email protected]/alunwcom/dotCMS.git (fetch) origin ssh://[email protected]/alunwcom/dotCMS.git (push) upstream https://github.com/dotCMS/dotCMS.git (fetch) upstream https://github.com/dotCMS/dotCMS.git (push) $ git fetch upstream # fetch changes from original repo ... $ git merge upstream/master # merge changes from original repo ... $ git push origin master ...
Setting Eclipse Project to Work with BitBucket
Having set-up a local repository - and its hosted counter-part - you need to configure this remote repository.
Use Team > Remote > Configure Push to Upstream
From the dialog box, select Advanced… and then Add All Branches Spec (and Add All Tags Spec).
Ditto for fetch??
In 'Git Repositories' view, set branch merge properties (to allow default master pull to work). Right-click the repository and select 'Properties'; then 'Add Entry…':
key: branch.master.remote value: origin key: branch.master.merge value: refs/heads/master
This can be edited directly in the Git repository (.git/config)
[branch "master"] remote = origin merge = refs/heads/master
Working with GitHub in Eclipse
Issue here is that GitHub will want to use SSH…
http://wiki.eclipse.org/EGit/User_Guide#GitHub_Tutorial
(I'm going to try and re-use the SSH certificate I generated previously for Linux CLI GitHub access.)
In Eclipse:
- Window > Preferences: General > Network Connections > SSH2
- Create new RSA key in Key Management tab.
- Check that this key is included under the General tab.
- Upload this (public) key to GitHub (account settings).
- Git Repositories: Configure Push…
- Edit the remote URI from https format to ssh. E.g.:
https://github.com/alunwcom/dotCMS.git --> ssh://[email protected]/alunwcom/dotCMS.git
- Save and Push
Done. Now want to add upstream remote for dotCMS/dotCMS repo.
Gitflow
CLI (tried below on Centos6): https://github.com/nvie/gitflow/wiki/Command-Line-Arguments
Create repo
$ mkdir gitflow-test $ cd gitflow-test/ $ git flow init Initialized empty Git repository in /home/dotcms/git2/gitflow-test/.git/ No branches exist yet. Base branches must be created now. Branch name for production releases: [master] Branch name for "next release" development: [develop] How to name your supporting branch prefixes? Feature branches? [feature/] Release branches? [release/] Hotfix branches? [hotfix/] Support branches? [support/] Version tag prefix? [] v $ git status # On branch develop nothing to commit (working directory clean)
Working on a Feature
$ git flow feature list No feature branches exist. You can start a new feature branch: git flow feature start <name> [<base>] $ git flow feature start initial-coding Switched to a new branch 'feature/initial-coding' Summary of actions: - A new branch 'feature/initial-coding' was created, based on 'develop' - You are now on branch 'feature/initial-coding' Now, start committing on your feature. When done, use: git flow feature finish initial-coding $ git flow feature list * initial-coding
...added stuff for feature... $ git status # On branch feature/initial-coding # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # new file: .gitignore # new file: src/com/wiley/test/Hello.java #
Belatedly added remote..
$ git remote add origin https://[email protected]/alunwcom/gitflow-test.git $ git push -u origin --all Password: Counting objects: 2, done. Writing objects: 100% (2/2), 167 bytes, done. Total 2 (delta 0), reused 0 (delta 0) remote: bb/acl: alunwcom is allowed. accepted payload. To https://[email protected]/alunwcom/gitflow-test.git * [new branch] develop -> develop * [new branch] feature/initial-coding -> feature/initial-coding * [new branch] master -> master Branch develop set up to track remote branch develop from origin. Branch feature/initial-coding set up to track remote branch feature/initial-coding from origin. Branch master set up to track remote branch master from origin.
Finish feature (which doesn't need to be 'published' now).
$ git flow feature finish initial-coding Switched to branch 'develop' Updating 242a2ed..8133d20 Fast-forward .gitignore | 3 +++ src/com/wiley/test/Hello.java | 10 ++++++++++ 2 files changed, 13 insertions(+), 0 deletions(-) create mode 100644 .gitignore create mode 100644 src/com/wiley/test/Hello.java Deleted branch feature/initial-coding (was 8133d20). Summary of actions: - The feature branch 'feature/initial-coding' was merged into 'develop' - Feature branch 'feature/initial-coding' has been removed - You are now on branch 'develop'
# [ISSUE?] Finishing the feature appears to have merged with fast-forward, thought gitflow would stop this? # [ISSUE?] Had to remote remote branch manually - maybe because I didn't use 'feature publish' $ git push origin :feature/initial-coding ...
Release..
$ git flow release start 0.1 Branches 'develop' and 'origin/develop' have diverged. And local branch 'develop' is ahead of 'origin/develop'. Switched to a new branch 'release/0.1' Summary of actions: - A new branch 'release/0.1' was created, based on 'develop' - You are now on branch 'release/0.1' Follow-up actions: - Bump the version number now! - Start committing last-minute fixes in preparing your release - When done, run: git flow release finish '0.1' $ git push --all $ git flow release finish 0.1 ... $ git push --all $ git push origin :release/0.1
