13.3 KB
Newer Older
Chris Bills's avatar
Chris Bills committed
## Contents of this Repository
Chris Bills's avatar
Chris Bills committed

Chris Bills's avatar
Chris Bills committed
3 4 5 6
*       - This README / Quick Start Guide
* bash-functions  - File that contains some example functions
* bash-git_prompt - An example colorful prompt for bash to show git status
* git-aliases     - Some example aliases for `~/.gitconfig`

Chris Bills's avatar
Chris Bills committed
Examples and more information about bash-functions, bash-git_prompt and git-aliases below the Getting Started guide.

More information about branching, forking, rebasing, merging and all that good stuff can be found in this excellent (and free!) online book:

12 13
### Getting Started with GitLab

Chris Bills's avatar
Chris Bills committed
14 15 16 17
Once you have an account on a GitLab server, you will want to set up your SSH key so that you can clone and contribute to projects hosted there.

**Note:** The examples below reference `xgitlab`; replace `xgitlab` with `gitlab` when working with ``

1. Generate an SSH keypair for GitLab (optional)
Chris Bills's avatar
Chris Bills committed
19 20 21 22 23 24 25

   You can use an existing keypair (e.g. `id_rsa` / ``) if you prefer, but it is generally a good idea to have unique keys for distinct services. If you already have a keypair you would like to use, skip this step.

   ssh-keygen -t rsa -b 2048 -f ~/.ssh/
   **Note:** This command will generate 2 files; `~/.ssh/` (your public key) and `~/.ssh/` (your private key).
26 27

1. Add your SSH public key to your account on GitLab:
Chris Bills's avatar
Chris Bills committed
28 29 30 31 32 33 34 35

   In order to authenticate your user with GitLab, you will need to provide the public portion of the keypair you wish to use to the GitLab service.

   1. Browse to:
   1. Copy your **public** key (the filename ends with `.pub`) to your clipboard
   1. Paste your public key into the "Key" field
   1. Set the "Title" to something meaningful
   1. Click "Add Key"
36 37 38

1. Add an entry for GitLab in your ~/.ssh/config file (Optional but very convenient)

Chris Bills's avatar
Chris Bills committed
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
   `~/.ssh/config` is your user's configuration file that is used by the ssh client. You can set the specific SSH options to use for new connections by adding an entry to the file, like below:

   Host  xgitlab
     User              git
     IdentityFile      ~/.ssh/

   Without the above entry in your SSH config, to clone a project, you might have to type:

   GIT_SSH_COMMAND='ssh -i ~/.ssh/' git clone

   But with the above entry in your SSH config, you can clone the project by typing:

   git clone xgitlab:cpbills/git-tips.git

60 61 62 63 64 65 66 67 68
### Setting the git author

Setting a user and email for git to add to a commit will let people know who is making the commits. Use the example below to set your name and email:

git config --global "John Smith"
git config --global ""

69 70
### Cloning a Repository

71 72 73 74 75
Once you've set up SSH, cloning a repository hosted on GitLab is pretty simple and straightforward.

The structure of a repository's URI is: $host:$namespace/$project.git (example: xgitlab:systems/git-tips.git).

Determine where you want to clone the repository; a directory like ~/projects/ works pretty well, but it really doesn't matter; wherever you are most comfortable working.
76 77

  * Change to your projects directory (e.g. `cd ~/projects`)
Chris Bills's avatar
Chris Bills committed
  * `git clone -o systems xgitlab:systems/git-tips.git`
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115

That's it.

You should now have a copy of the Git Tips repository in ~/projects/git-tips (or wherever, you non-conformist, you...) It is cloned and the only remote repository (simply 'remote' for short) it knows about is named 'systems' (-o <name> gives the remote a name, the default is origin).

### Branch Workflow

In a branch-style workflow, contributors either maintain long-lived personal branches of a project, or create (and destroy) shorter lived branches for bringing in new features or fixing bugs.

Creating a new branch:

cd ~/projects/git-tips
git checkout -b foo     # create and checkout the branch 'foo'

You can change between branches by typing `git checkout <name_of_branch>`.

git checkout foo          # Change to local branch 'foo'
git merge --no-ff master  # Merge changes from 'master into the currently checked out branch; Creates a merge commit
git rebase master         # Rebase current branch on the commit master points to;
                          # e.g. Apply commits from master, then apply current branch commits

### Fork Workflow

The fork-style workflow is more complicated than the branch-style workflow because it necessitates working with multiple remotes, but is easier for individual contributors to work with, since you have a long-lived development environment set up.

Forking creates a clone of a particular project in your own personal name-space. This allows you to do your development work out of the way of anyone else, and work on features and bug fixes until they are ready to be shared with others.

The fork-style workflow is useful when there are numerous contributors managing long-lived branches on the main repository.

"Rewriting history" using tools like `git rebase` is a much smaller issue when working with a personal fork.

Forking a repository on GitLab:

* Make sure you're logged in to to use this example
Chris Bills's avatar
Chris Bills committed
* Browse to
118 119 120 121 122 123
* Click the button in the top right that says 'Fork'
* Select the namespace you want to create the fork in

Getting set up with your fork and multiple remotes:

Chris Bills's avatar
Chris Bills committed
124 125
git clone -o foo xgitlab:foo/git-tips.git           # Clone your fork
git remote add systems xgitlab:systems/git-tips.git # Add the 'systems' remote
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142

You now have two remotes; 'foo' and 'systems'. You can push or pull code using either of them:

git push foo master             # Push local branch 'master' to remote 'foo'
git push systems master         # Push local branch 'master' to remote 'systems'
git push systems master:foo     # Push local branch 'master' to remote 'systems', branch 'foo'
git pull systems foo            # Pull changes from remote 'systems', branch 'foo'
git rebase bar systems/master   # Rebase your local branch 'bar' on top of the branch 'master' on systems; changes made to your local branch only

Ignore the 'rebase' example above if you're unfamiliar with rebase; it's only there for an example of how you can work with remotes. For more information about git, please read through [Pro Git](

### Contributing Changes

Whether you're using the fork or branch workflow, contributing your changes is pretty much the same process (at least when using GitLab).

Once you have made changes that you would like to contribute to a project, you will need to notify the maintainers (or "owners") of the project by making a Merge Request, within GitLab's Web UI.

Making a Merge Request will send an email to the person you assign it to, and will show a diff of your branch versus the branch you are asking to merge your changes into. Follow the steps below to make a Merge Request in GitLab:

149 150 151 152 153 154 155 156 157 158 159
1. Browse to the project's page on GitLab (e.g. OR your forked repository's page
1. Locate and click '+ New Merge Request' near the top right of the page (Subject to change as GitLab evolves)
1. Select your source project and branch (e.g. systems/git-tips and 'foo', or username/git-tips and 'foo')
1. Select your target project and branch (e.g. systems/project and 'prod')
1. Click 'Compare Branches'
1. Describe what your branch does and what testing you've done: don't rely on commit messages.
1. Click 'Submit new merge request'

Now your changes are ready to be reviewed. The project maintainers may have followup questions for you or ask you to make changes.

Make any changes, as needed, and comment on the Merge Request when you are ready for another review. As long as you push your changes to the same branch of your initial Merge Request, you should not need to create another one.
160 161 162

### Bringing in Changes

163 164 165 166 167
If you are the maintainer of a project, you may need to respond to Merge Requests and occasionally bring changes in to the 'production' branch from contributor's forks or branches.

How you bring those changes in depends on your preferences; some people prefer merging and merge commits, where others prefer a cleaner / more linear history and using 'rebase'.

If you are responsible for maintaining a project, do yourself a favor and read about the various methods people use for bringing in changes.

Merging is easy, especially within GitLab, because it can essentially all be done through the web interface using Merge Requests. Rebase (in my opinion) provides a clearer linear history of the project, but requires more understanding of git than this simple guide strives to impart.

[Information on rebasing](
Chris Bills's avatar
Chris Bills committed

[Rebase vs. Merge](
Chris Bills's avatar
Chris Bills committed

[Information on merging](
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195

### Migrating a Repository from Other Services

The process is fairly straightforward:

* Create a new project on GitLab; either a user or group project
* Clone the project from the original service (if it has not already been cloned somewhere you can work with it)
* Add a remote for the new GitLab project you created
* Push the repository to your new GitLab remote

git clone -o source <source_URI> migrate    # (optional) Clone the repository from the other service into the directory 'migrate'

# Checkout all remote branches locally (optional)
for branch in $(git branch -r | grep source | grep -v HEAD); do
  git branch --track "$branch" source/"$branch"

# Where 'namespace' is the user/group, and 'project' is the name of the project on GitLab:
Chris Bills's avatar
Chris Bills committed
196 197 198
git remote add xgitlab xgitlab:<namespace>/<project>.git
git push xgitlab --all     # Push all local branches to the new remote
git push xgitlab --tags    # Push any local tags to GitLab (optional)
Chris Bills's avatar
Chris Bills committed
200 201

### bash-functions
#### About
Chris Bills's avatar
Chris Bills committed
The [bash-functions](/bash-functions) file contains some example functions that can be helpful when working with git. If you have suggestions, additions or fixes, you are encouraged to submit merge requests.
Chris Bills's avatar
Chris Bills committed

205 206 207
1. `gits [#]` - a function that displays a brief summary of changes and the previous 5 log messages and hash commits. If an optional number is provided, it will display that many log messages.

#### Usage
208 209 210 211 212 213 214 215
Copy the contents of `bash-functions` into `~/.bashrc` or copy the file somewhere in your home directory and add something like the following to `~/.bashrc`:

if [[ -e "$HOME/.bash_functions" ]]; then
  source "$HOME/.bash_functions"

Chris Bills's avatar
Chris Bills committed
### bash-git_prompt
#### About
Chris Bills's avatar
Chris Bills committed
The [bash-git_prompt](/bash-git_prompt) file contains some functions and configuration for adding git status information to your current prompt. It is meant as an example, you are encouraged to tweak it to meet your needs and suggest additions, fixes or updates.
219 220 221

#### Usage
You can copy it wholesale into your `~/.bashrc` configuration file, or you can add something like the following to `~/.bashrc` to source a file:
222 223 224 225 226 227 228 229 230

if [[ -e "$HOME/.bash_git_prompt" ]]; then
  source "$HOME/.bash_git_prompt"

**Note:** If you are using `$PROMPT_COMMAND` in your `~/.bashrc` already, you will need to take some care and adjust the contents of `bash-git_prompt`

Chris Bills's avatar
Chris Bills committed
231 232 233 234 235 236 237 238 239 240 241 242
#### Symbol meanings:
* `>` - Local branch is ahead of the branch it is tracking
* `<` - Local branch is behind the branch it is tracking
* `!` - Local and remote branches have diverged
* `+` - There is at least 1 local `stash`
* `?` - There are files in the git working directory that are untracked


![example prompt and gits output](media/example.png)

### git-aliases
#### About
Chris Bills's avatar
Chris Bills committed
The [git-aliases](/git-aliases) file contains a handful useful git aliases. These can be placed in `~/.gitconfig` (recommended) or within a project's git config (not recommended).
245 246

As with everything else, if you have additions, fixes or updates, you are encouraged to share them.
Chris Bills's avatar
Chris Bills committed
247 248 249 250 251 252 253 254 255

* `co` - Alias for `checkout`, easier and quicker to type
* `last` - Display information about the most recent commit
* `unstage` - Reverse a `git add <file>` with `git unstage <file>`
* `ls` - list all the files currently tracked by git
* `vis` - display a pretty listing of log messages with a graph of the branching
* `today` - (Requires git v1.8+) displays log of commits since yesterday; e.g. today's commits
* `squash` - Does an interactive rebase of the previous # commits; useful for squashing commits
* `stashed` - Display information about stashes
* `history` - Show the history of a file, branch or other ref including commit messages and diff / patch
Chris Bills's avatar
Chris Bills committed

258 259
#### Usage
Copy the aliases from `git-aliases` that you want to use into `~/.gitconfig`

Chris Bills's avatar
Chris Bills committed
### Push Notifications
262 263 264
Gitlab does not natively implement push notifications on repositories.  You can set your preferences on what you'd like to be notified about following [these docs]( but you'll find "push" is not included.

To be included on push notifications, the project owner needs to specifically enable it and add your e-mail to the list.  This can be done via<path-to-repo>/services/emails_on_push/edit by anyone with admin rights on the project.  If you do not have those rights, ask the project owner to do so for you.