README.md 8.65 KB
Newer Older
1
2
##### Note; Replace gitlab.cels.anl.gov with xgitlab.cels.anl.gov if you are accessing or working with xgitlab.cels.anl.gov.

Chris Bills's avatar
Chris Bills committed
3
4
5
### Getting Started with GitLab

1. Generate an SSH keypair for GitLab (optional)
Chris Bills's avatar
Chris Bills committed
6
  * `ssh-keygen -t rsa -b 2048 -f ~/.ssh/gitlab.cels.anl.gov`
Chris Bills's avatar
Chris Bills committed
7
8
9
10
11
12
13
14
15

1. Add your SSH public key to your account on GitLab:
  1. Browse to: https://gitlab.cels.anl.gov/profile/keys
  1. Click Add SSH Key (top-right)
  1. Set the title to something meaningful
  1. Copy your public key and paste it into the Key field
  1. Click Add Key

1. Add an entry for GitLab in your ~/.ssh/config file (Optional but very convenient)
Chris Bills's avatar
Chris Bills committed
16
  * This will allow you to type something like `git clone gitlab:namespace/project.git` without needing to pass a username, fqdn, or ssh identity to git
Chris Bills's avatar
Chris Bills committed
17
18
19
20
21

```
Host  gitlab
  User              git
  Hostname          gitlab.cels.anl.gov
Chris Bills's avatar
Chris Bills committed
22
  IdentityFile      ~/.ssh/gitlab.cels.anl.gov
Chris Bills's avatar
Chris Bills committed
23
```
Chris Bills's avatar
Chris Bills committed
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

### bash-functions

A file that contains some example functions that can be helpful when working with git.

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.

### bash-git_prompt

An example addition to the bash prompt that will show you which branch you currently have checked out, and what its status is.

#### 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:

`fool [git-tips:master?+>]$` (only imagine it in color... yeah, real helpful, I know...)

This means the local branch `master` is ahead of the remote branch it is tracking, there is at least one stash, and there are untracked files present.
47
48
49
50
51
52
53
54
55
56
57
58
59

### git-aliases

A collection of useful git aliases. These can be placed in `~/.gitconfig` (recommended) or within a project's git config (not recommended).

* `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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175

### Cloning a Repository

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

  * Change to your projects directory (e.g. `cd ~/projects`)
  * `git clone -o systems gitlab:systems/git-tips.git`

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:

* Browse to https://gitlab.cels.anl.gov/systems/git-tips.git
* 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:

```
git clone -o foo gitlab:foo/git-tips.git            # Clone your fork
git remote add systems gitlab:systems/git-tips.git  # Add the 'systems' remote
```

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](https://git-scm.com/book/en/v2).


### Contributing Changes

Whether using the fork or branch workflows, contributing changes to a project (at least through GitLab) is pretty much the same.

When all is said and done, and you have work that is ready to be reviewed by others and potentially pushed to 'production', you will need to create a Merge Request on GitLab:

* Browse to the project's page on GitLab (e.g. https://gitlab.cels.anl.gov/systems/git-tips.git) OR your forked repository's page
* Locate and click '+ New Merge Request' near the top right of the page (Subject to change as GitLab evolves)
* Select your source project and branch (e.g. systems/git-tips and 'foo', or username/git-tips and 'foo')
* Select your target project and branch (e.g. systems/project and 'prod')
* Click 'Compare Branches'
* Describe what your branch does and what testing you've done: don't rely on commit messages.
* Click 'Submit new merge request'
* Notify the main maintainer(s) of the project (they should receive an email, but...)

Your changes will be reviewed, and the maintainer(s) may have follow up questions for you or may ask you to make some changes, or squash some commits and generally clean things up.

### Bringing in Changes

This is a heated topic in some circles; some people prefer merging and merge commits, where others prefer a cleaner history and rebasing. The style should be determined by the maintainer(s), I personally prefer rebasing.

I'd rather leave this hazy, for the time being, until people get more familiar with git; information about both methods is readily available.

Merging is easiest, especially with GitLab, because it can essentially all be done through the web interface.

### 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
  branch="${branch##*/}"
  git branch --track "$branch" source/"$branch"
done

# Where 'namespace' is the user/group, and 'project' is the name of the project on GitLab:
git remote add gitlab gitlab:<namespace>/<project>.git
git push gitlab --all     # Push all local branches to the new remote
git push gitlab --tags    # Push any local tags to GitLab (optional)
```