Skip to content

Abbreviated git Workflow

Rowdy edited this page May 9, 2017 · 88 revisions

A quick reference for several commands

Contents

  1. Abstract
    1. Things done only once
    2. Things done once per repository
    3. Things done for each major enhancement
  2. Initially configuring a git workstation
  3. Creating a new project
  4. Initially obtaining an existing project
  5. Checking the status of your files
    1. Checking the selected branch
    2. Checking for uncommitted changes
  6. Committing changes
  7. Pushing to the remote repository
  8. Creating a new branch
  9. Switching to an existing branch
  10. Switching between existing branches
  11. Pulling changes from a remote repository
  12. Deleting a branch
  13. Creating an issue
  14. Resolving a conflict (into develop)
  15. Resolving a conflict (into same branch)
  16. Viewing a commit log
  17. Performing releases
  18. Reverting to an original file
  19. Merging changes from another branch into your feature branch
  20. Excluding files from commit
  21. References
  22. TODO

Abstract

This document provides a quick reference guide for several potentially useful git commands.

Things done only once

Things done once per repository

Things done for each major enhancement

For example, the following vague workflow would apply to each separate incident that is to be addressed.


Initially configuring a git workstation

  1. Define the name you want attached to your commit transactions:

    $ git config --global user.name "<name>"
    
  2. Define the email you want attached to your commit transactions:

    $ git config --global user.email "<email address>"
    
  3. Enables helpful colorization of command line output:

    $ git config --global color.ui auto
    
  4. Define the conflict resolution utility (kdiff3 has been recommended, and should be installed first):

    $ git config --global merge.tool kdiff3
    
  5. 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).


Creating a new project

  • 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
    

Initially obtaining an existing project

  1. 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.

  2. Change to the parent directory e.g. C:\eclipse_workspace or ~/git

  3. Issue command:

    $ git clone <url>
    

    For example:

    $ git clone git@github.com:fieldenms/t64airways.git
    
  4. 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
    

Checking the status of your local files

Checking the selected branch

  • 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
    

Checking for uncommitted changes:

  • 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")
    

Committing changes

  1. Check for changes to commit.

  2. 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
     ------------------------------------------------------------------------------------------------------------------------
    
  3. 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).

  4. Select files from one logical group for comitting (repeat for each file to commit):

    $ git add <file>
    

    For example:

    $ git add readme.txt
    
  5. 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."
    
  6. Repeat steps 4 and 5 for each of the remaining logical groups of files.

  7. 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.


Pushing to the remote repository

  1. 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.


Creating a new 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.
  1. 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
    
  2. 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.


Switching to an existing branch

  1. Identify the branch to, which you want/need to switch.

  2. Issue command:

    $ git checkout <branch>
    

    For example:

    $ git checkout incident-16168
    
  3. Update your local repository.


Switching between existing branches

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).

  1. Commit and push the changes in the original feature branch. Committing locally is essential. Pushing is optional, but recommended.

  2. 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.

  3. Perform consultancy in the other feature branch, commit and push changes as required.

  4. Switch back to the original feature branch.

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.


Pulling changes from a remote repository

  1. Ensure you are in the appropriate branch.

  2. 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(-)
    

Deleting a branch

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.

  1. Switch to the develop branch (or another branch that is not about to be deleted):

    $ git checkout develop
    
  2. Delete the local branch:

    $ git branch --delete <branch>
    

    For example:

    $ git branch --delete incident-16168
    
  3. Delete the remote branch:

    $ git push origin --delete <branch>
    

    For example:

    $ git push origin --delete incident-16168
    
  4. Anyone who has the branch checkouted should also remove references to branches deleted on the server:

    $ git remote prune origin
    
  5. 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
    

Creating an issue

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.

Resolving a conflict

  1. 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
    
  2. Ensure you have the latest changes:

    $ git pull
    
  3. 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.
    
  4. Invoke the merge tool to assist with resolving the conflicts:

    $ git mergetool
    

Resolving a conflict - same branch

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.

  1. Attempt to commit your local changes.

  2. Attempt to bring in the changes performed by the other consultant, which will probably report that changes need to be manually merged:

    $ git pull
    
  3. 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
    
  4. 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.

  5. 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.


Viewing a commit log

  • 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


Performing releases

Please make reference to the respective build and release checklist where the necessary commands and workflow processes are described.


Reverting to an original file

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>

Merging changes from another branch into your feature branch

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.

  1. Ensure you are on your feature branch.

  2. Ensure that your feature branch is up to date (in case another consultant has committed/pushed changes.)

  3. 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.


Excluding files from commit

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.

  1. Add a file to the "ignore" list:

    $ git update-index --assume-unchanged <file>
    
  2. List files in the "ignore" list:

    $ git ls-files -v | grep '^h'
    

    or:

    $ git ls-files -v | grep '^h' | cut -c3-
    
  3. Remove a file from the "ignore" list:

    $ git update-index --no-assume-unchanged <file>
    

References


TODO

  • Nothing.
Clone this wiki locally