Abbreviated git Workflow - fieldenms/tg GitHub Wiki
- Abstract
- Initially configuring a git workstation
- Creating a new project
- Initially obtaining an existing project
- Checking the status of your files
- Committing changes
- Pushing to the remote repository
- Creating a new branch
- Switching to an existing branch
- Switching between existing branches
- Pulling changes from a remote repository
- Deleting a branch
- Creating an issue
- Resolving a conflict (into develop)
- Resolving a conflict (into same branch)
- Viewing a commit log
- Performing releases
- Reverting to an original file
- Merging changes from another branch into your feature branch
- Excluding files from commit
- References
- TODO
This document provides a quick reference guide for several potentially useful git commands.
For example, the following vague workflow would apply to each separate incident that is to be addressed.
-
When starting consultancy:
-
switch to the develop branch (or the appropriate parent branch)
git checkout develop
-
update local repository/s (develop branch)
git pull
-
create (inherited from develop) and switch to a new feature branch for the incident
git checkout -b Incident-nnnnn develop
-
create an issue for each subset of the main feature e.g. for each item in a quotation
-
git checkout -b Issue-#nnn Incident-nnnnn
-
-
During consultancy:
-
update local repository/s (feature subset branch Issue-#nnn)
git pull
-
perform consultancy (in the issue feature subset branch Issue-#nnn)
-
git add <file> ...
git commit -m "#nnn technical commit message"
or
git add .
git commit -m "#nnn technical commit message"
-
push to the remote repository (for other consultants to checkout/review/assist)
git push
-
if the feature subset (the single item from the quotation) is finalised, the feature subset branch (Issue-#nnn) can be merged into the main feature branch (incident-nnnnn) (can be done with GitHub pull requests) and the feature subset branch (Issue-#nnn) can be deleted
-
-
When finishing consultancy:
-
close the issue/s (can be done via the commit message or via GitHub)
-
git push
-
(via GitHub) issue a pull request
-
(via GitHub) merge the feature branch into the develop branch (or the appropriate parent branch)
-
switch back to the develop branch
git checkout develop
-
delete the feature branch locally and remotely
git branch --delete incident-nnnnn
git push origin --delete incident-nnnnn
-
(via WeBaCC2) transfer the incident
-
(if applicable) perform an integration/SIT release
-
(via WeBaCC2 if applicable) send invoice to client
-
-
Define the name you want attached to your commit transactions:
$ git config --global user.name "<name>"
-
Define the email you want attached to your commit transactions:
$ git config --global user.email "<email address>"
-
Enables helpful colorization of command line output:
$ git config --global color.ui auto
-
Define the conflict resolution utility (kdiff3 has been recommended, and should be installed first):
$ git config --global merge.tool kdiff3
-
Define the default push behaviour:
$ git config --global push.default simple
Note that git configuration is stored in C:/Users/username/.gitconfig (Microsoft) or ~/.gitconfig (everything else).
-
To create a new local repository for local commits only:
$ mkdir my-project $ cd my-project $ git init
-
To create a new repository on a server, for others to clone and/or push to (note the .git extension to the directory name, used as a convention):
$ mkdir my-project.git $ cd my-project.git $ git init --bare
-
Identify the project URL, for example on GitHub visit the main project page and find the "SSH clone URL" to the right of the page.
-
Change to the parent directory e.g. C:\eclipse_workspace or ~/git
-
Issue command:
$ git clone <url>
For example:
$ git clone [email protected]:fieldenms/t64airways.git
-
Alternatively find/select the "HTTPS clone URL" on the project's GitHub page, and issue a similar command, for example:
$ git clone https://github.com/fieldenms/t64airways.git
-
To check, which branch you are on, and, which branches are available locally:
C:\eclipse_workspace\t64airways [develop]> git branch
For example (noting that the branch with the asterisk is the currently selected branch):
C:\eclipse_workspace\t64airways [develop]> git branch * develop
-
To check, which branches are available on the remote server:
C:\eclipse_workspace\t64airways [develop]> git branch -r
For example (no branch has an asterisk because this is only a list of remote branches):
C:\eclipse_workspace\t64airways [develop]> git branch -r origin/HEAD -> origin/develop origin/incident-16060 origin/PoLineAuthorisation origin/develop origin/master
-
To show a list of all branches, local and remote:
C:\eclipse_workspace\t64airways [develop]> git branch -a
For example (noting that the branch with the asterisk is the currently selected branch):
C:\eclipse_workspace\t64airways [develop]> git branch -a * develop remotes/origin/HEAD -> origin/develop remotes/origin/incident-16060 remotes/origin/PoLineAuthorisation remotes/origin/develop remotes/origin/master
-
To show the last commit on the current branch:
C:\eclipse_workspace\t64airways [develop +1 ~1 -0 !]> git branch -v * develop 4b1e1a4 Closes #4 - Implemented further tweaks to changing PO from Local to International and back
-
To show the last commit on all branches:
C:\eclipse_workspace\t64airways [develop +1 ~1 -0 !]> git branch -v -a * develop 4b1e1a4 Closes #4 - Implemented further tweaks to changing PO from Local to International and back remotes/origin/HEAD -> origin/develop remotes/origin/incident-16060 73b8c06 #7 - Continue to implement Labour Performance Analysis. remotes/origin/PoLineAuthorisation 96734a7 #1 Merge changes from Develop remotes/origin/develop 4b1e1a4 Closes #4 - Implemented further tweaks to changing PO from Local to International and back remotes/origin/master 2ce9f65 ml 1-401 16168 - t64airways migration from CVS to GitHub
-
To check for uncommitted changes:
C:\eclipse_workspace\t64airways [develop]> git status
For example (showing that there are no uncommitted changes):
C:\eclipse_workspace\t64airways [develop]> git status On branch develop Your branch is up-to-date with 'origin/develop'. nothing to commit, working directory clean
For example (showing that there are some uncommitted changes (new and edited files)):
C:\eclipse_workspace\t64airways [develop +1 ~1 -0 !]> git status On branch develop Your branch is up-to-date with 'origin/develop'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: readme.txt Untracked files: (use "git add <file>..." to include in what will be committed) new_file.txt no changes added to commit (use "git add" and/or "git commit -a")
-
If desired, check for details of what has changed in those files:
C:\eclipse_workspace\t64airways [develop +1 ~1 -0 !]> git diff
For example:
C:\eclipse_workspace\t64airways [develop +1 ~1 -0 !]> git diff diff --git a/readme.txt b/readme.txt index a7bc8c0..c648340 100644 --- a/readme.txt +++ b/readme.txt @@ -1,6 +1,6 @@ MapBar -When Bld Who Mle Who4 Mod What +When Bld Who Mle Proj Inc What ------------------------------------------------------------------------------------------------------------------------ 28-Nov-2003 MapBar 4.0 Build 58 Production (based on 4.0 Build 57 Production) tagged as AIRWAYS_4_0_BUILD_58 ------------------------------------------------------------------------------------------------------------------------
-
Conceptually collect files into logical groups for separate commits (e.g. SQL scripts in one commit, work order forms in a second commit, reports in a third commit).
-
Select files from one logical group for comitting (repeat for each file to commit):
$ git add <file>
For example:
$ git add readme.txt
-
Commit the file/s (noting that the commit message should always reference the respective issue):
$ git commit -m "<commit message>"
For example:
$ git commit -m "#17 Enhanced the line-up to consist simply of six hydrocoptic marzel vanes so fitted to the ambifacient lunar wane shaft that side-fumbling was effectively prevented."
-
Repeat steps 4 and 5 for each of the remaining logical groups of files.
-
Alternatively, commit all changes as one big commit (less recommended):
$ git add . $ git commit -m "<commit message>"
Commit messages should be of a technical nature and do not need to include project code or incident number. They should always reference the respective GitHub issue. Release notes are to be constructed from issue descriptions, not commit messages.
A commit can close the respective GitHub issue by includig text like "closes #n" in the commit description.
Note that at this stage changes have been committed locally only, and for full transparency should be pushed to the remote repository.
-
After changes have been committed locally, push them to the remote repository:
$ git push
Changes that are not pushed to the remote repository cannot be checkouted by other consultants.
Note that changes should always be done in a feature branch for the specific incident or issue, and should always be pushed to the remote repository within that feature branch. Only later on will they be merged into the develop branch.
Branch names should be as follows:
-
master
- The main branch, used for releases to clients. No-one should be committing into this branch. -
develop
- A generic consultancy branch into, which completed feature branches should be merged. -
release-x.y
- A branch representing a formal release to a client. -
hotfix-x.y.z
- A hotfix branch representing an incremental upgrade to a previous formal release to a client. -
Incident-nnnnn
- A feature branch relating to an incident. -
Incident-nnnnn.m
- A subsequent feature branch based on an earlier feature branch, which has already been deleted, when additional changes are suddenly required. -
Issue-#nnn
- A feature branch relating to an issue.
-
Create a new git branch based on the incident number (the base branch is usually develop). Ensure that the base branch is up to date before creating the new branch:
$ git checkout -b <branch> <base-branch>
For example:
$ git checkout -b incident-16168 develop
-
Push the new feature branch to the origin (the parent repository):
$ git push -u origin <branch>
For example:
$ git push -u origin incident-16168
Pushing the new branch to the origin will allow other consultants to checkout it.
-
Issue command:
$ git checkout <branch>
For example:
$ git checkout incident-16168
For example in the situation where you are performing consultancy for one incident (in one feature branch), and are required to take a break and perform consultancy on a different incident (in a different feature branch).
-
Commit and push the changes in the original feature branch. Committing locally is essential. Pushing is optional, but recommended.
-
Switch to the other branch, noting that the other consultant needs to have created and pushed the branch, committed their changes locally (local to them), and pushed the changes to the central repository.
-
Perform consultancy in the other feature branch, commit and push changes as required.
To avoid disrupting a carefully constructed consultancy environment an alternative approach is to simply clone the repository into a new directory, switch to the second feature branch there, and perform consultancy completely isolated from the original consultancy environment and feature branch.
-
Issue command:
$ git pull
For example:
C:\eclipse_workspace\t64airways [develop +1 ~1 -0 !]> git pull Warning: Permanently added 'github.com,192.30.252.128' (RSA) to the list of known hosts. remote: Counting objects: 35, done. remote: Compressing objects: 100% (35/35), done. remote: Total 35 (delta 12), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (35/35), done. From github.com:fieldenms/t64airways 4f521e5..245bfb8 develop -> origin/develop 90747a0..1304cef PoLineAuthorisation -> origin/PoLineAuthorisation Updating 4f521e5..245bfb8 Fast-forward MapBar/MapBar.dof | 4 ++-- common/t32lib.pas | 2 +- por/Pordmun.dfm | 1 + por/Pordmun.dti | 4 ++-- por/Pordmun.pas | 68 ++++++++++++++++++++++++++++++++++++++++++----------- por/por010un.dfm | 1 - por/por010un.pas | 13 ++++++---- tab/Tab011un.dfm | 4 ++-- tab/Tab011un.pas | 4 ++-- wor/wohistoryun.dfm | 19 +++++++++++---- wor/wohistoryun.pas | 59 ++++++++++++++++++++++++++++++++++------------ 11 files changed, 131 insertions(+), 48 deletions(-)
A branch should only be deleted after any associated changes have been merged back into a more permanent branch.
If it becomes known that additional changes are required, and the branch has already been deleted, then create a new branch with a .m suffix, for example incident-16168.1
.
-
Switch to the develop branch (or another branch that is not about to be deleted):
$ git checkout develop
-
Delete the local branch:
$ git branch --delete <branch>
For example:
$ git branch --delete incident-16168
-
Delete the remote branch:
$ git push origin --delete <branch>
For example:
$ git push origin --delete incident-16168
-
Anyone who has the branch checkouted should also remove references to branches deleted on the server:
$ git remote prune origin
-
Occasionally (or perhaps frequently) a local list of branches might include many branches that have already been deleted from the server. The following command attempts to compensate for that:
$ git fetch -p
Issues are created using the GitHub issue facility. There is generally at least one issue for each incident, but could be many more.
Issue short description should contain project code, incident number, a brief description of the change.
For example: 1-401 16168 Creation of GitHub wiki page for git
Issue long description should contain an incident tag, and a user-friendly description of the change. This description (excluding the incident tag) will be used to form the release notes.
For example:
incident: 16168
Create a GitHub wiki page providing a quick reference to commonly used and useful git commands.
-
Switch to the develop branch (or whichever branch the change is to be merged into, usually develop). This is where the feature branch needs to be merged into:
$ git checkout develop
-
Ensure you have the latest changes:
$ git pull
-
Attempt to merge the feature branch. --no-ff causes the merge to always create a new commit object, even if the merge could be performed with a fast-forward. This avoids losing information about the historical existence of a feature branch and groups together all commits that together added the feature.
$ git merge --no-ff <branch>
For example:
$ git merge --no-ff incident-16168
In the event that the merge undergoes upgrade, a warning message similar to the following will be displayed:
Auto-merging directory/file.ext CONFLICT (content): Merge conflict in directory/file.ext Automatic merge underwent upgrade; fix conflicts and then commit the result.
-
Invoke the merge tool to assist with resolving the conflicts:
$ git mergetool
If two consultants are performing consultancy in the same branch and have modified the same file independantly, the changes will need to be merged. git will advise if it is unable to merge automatically.
-
Attempt to bring in the changes performed by the other consultant, which will probably report that changes need to be manually merged:
$ git pull
-
Check the status of the local repository:
$ git status
, which might respond with something similar to this example:
C:\eclipse_workspace\t64airways [incident-16129 +0 ~2 -0 !2 | +0 ~0 -0 !2]> git status On branch incident-16129 Your branch and 'origin/incident-16129' have diverged, and have 1 and 5 different commits each, respectively. (use "git pull" to merge the remote branch into yours) You have unmerged paths. (fix conflicts and run "git commit") Changes to be committed: modified: wor/formBRDLeaveRequestWizard.dfm modified: wor/formBRDLeaveRequestWizard.pas Unmerged paths: (use "git add <file>..." to mark resolution) both modified: wor/formTimesheet.dfm both modified: wor/formTimesheet.pas
-
Invoke the previously configured merge tool to facilitate the manual merging:
$ git mergetool
This should invoke the merge tool (e.g. kdiff3) for each file that needs to be manually merged. As each file is merged and saved, and the merge tool closed, the git command will automatically proceed to the next file that needs manual merging, until all conflicts have been resolved.
In the case of kdiff3, it is probably the case that the common base file appears in the left pane, the local changes appear in the middle pane, and the remote changes appear in the right pane. The lower pane shows the results of the merge. Pressing ^2 will copy the changes from the local file, pressing ^3 will copy the changes from the remote file, and both can be pressed if both changes are required.
-
Commit the merged file/s and push them to the remote repository
Note that if user 1 changes, commits and pushes 10 files, and user 2 changes one of those same files, when user 2 resolves the conflict user 2 will have all 10 files apparently changed and ready for commit. This probably has something to do with the way in, which git handles a commit as an atomic object - if user 2 resolves a conflict with one file in a commit "batch", they will need to commit all files in that batch, not just the file that they have resolved.
-
To review all commits since "last month" with a format similar to CSV (output is piped to a file):
$ git log --since='last month' --pretty=format:'%h,%an,%ar,%s' > log.csv
-
To review all commits since a particular tag:
Identify the tag:
$ git tag -l -n
List all commits since a particular tag (e.g. 1.2):
$ git log --pretty=format:%s 1.2..HEAD
-
For more information on git logs and the available output formats see: http://git-scm.com/docs/git-log
Please make reference to the respective build and release checklist where the necessary commands and workflow processes are described.
To revert to an original (repository) copy of a file and discard the changes recently consulted to that file:
$ git checkout <file>
However this will conflict if there is a branch with the same name as the file (unlikely, but just in case), in, which case the branch will be reverted, not just the file. In that situation the following syntax should be used:
git checkout -- <file>
For example if you are consulting on a feature branch and another consultant commits/pushes/merges changes into branch develop
that you need, you can merge branch develop
into your feature branch.
For another example if you are consulting on a feature branch and another consultant commits/pushes changes into a different feature branch, you can merge the other feature branch into your feature branch.
-
Ensure that your feature branch is up to date (in case another consultant has committed/pushed changes.)
-
Merge changes from the other feature branch (or branch
develop
):$ git merge --no-ff <branch>
For example:
$ git merge --no-ff origin/develop
Note that it seems to be necessary (at least it is suggested by the git command) to add the
origin/
prefix to the branch name, presumably to indicate that the changes being merged should be obtained from the origin (upstream server) rather than locally.Note that sometimes it might be reported that the feature branch is already up to date, when it is known that it is not. git will respond with a message like
Already up-to-date.
. In those situations checkout the branch you are trying to bring in (e.g.git checkout develop
),git pull
to update it, checkout the feature branch, and try to merge again.
Sometimes it might be useful to ignore local changes to the tracked in Git files in order to avoid accidental commits. For example property and ini files that might have your specific settings for the consultancy session you're experiencing.
-
Add a file to the "ignore" list:
$ git update-index --assume-unchanged <file>
-
List files in the "ignore" list:
$ git ls-files -v | grep '^h'
or:
$ git ls-files -v | grep '^h' | cut -c3-
-
Remove a file from the "ignore" list:
$ git update-index --no-assume-unchanged <file>
- Nothing.