1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
|
---
category: tool
tool: git
contributors:
- ["Jake Prather", "http://github.com/JakeHP"]
- ["Leo Rudberg" , "http://github.com/LOZORD"]
- ["Betsy Lorton" , "http://github.com/schbetsy"]
filename: LearnGit.txt
---
Git is a distributed version control and source code management system.
It does this through a series of snapshots of your project, and it works
with those snapshots to provide you with functionality to version and
manage your source code.
## Versioning Concepts
### What is version control?
Version control is a system that records changes to a file, or set of files, over time.
### Centralized Versioning VS Distributed Versioning
* Centralized version control focuses on synchronizing, tracking, and backing up files.
* Distributed version control focuses on sharing changes. Every change has a unique id.
* Distributed systems have no defined structure. You could easily have a SVN style, centralized system, with git.
[Additional Information](http://git-scm.com/book/en/Getting-Started-About-Version-Control)
### Why Use Git?
* Can work offline.
* Collaborating with others is easy!
* Branching is easy!
* Merging is easy!
* Git is fast.
* Git is flexible.
## Git Architecture
### Repository
A set of files, directories, historical records, commits, and heads. Imagine it as a source code data structure,
with the attribute that each source code "element" gives you access to its revision history, among other things.
A git repository is comprised of the .git directory & working tree.
### .git Directory (component of repository)
The .git directory contains all the configurations, logs, branches, HEAD, and more.
[Detailed List.](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
### Working Tree (component of repository)
This is basically the directories and files in your repository. It is often referred to
as your working directory.
### Index (component of .git dir)
The Index is the staging area in git. It's basically a layer that separates your working tree
from the Git repository. This gives developers more power over what gets sent to the Git
repository.
### Commit
A git commit is a snapshot of a set of changes, or manipulations to your Working Tree.
For example, if you added 5 files, and removed 2 others, these changes will be contained
in a commit (or snapshot). This commit can then be pushed to other repositories, or not!
### Branch
A branch is essentially a pointer that points to the last commit you made. As you commit,
this pointer will automatically update and point to the latest commit.
### HEAD and head (component of .git dir)
HEAD is a pointer that points to the current branch. A repository only has 1 *active* HEAD.
head is a pointer that points to any commit. A repository can have any number of heads.
### Conceptual Resources
* [Git For Computer Scientists](http://eagain.net/articles/git-for-computer-scientists/)
* [Git For Designers](http://hoth.entp.com/output/git_for_designers.html)
## Commands
### init
Create an empty Git repository. The Git repository's settings, stored information,
and more is stored in a directory (a folder) named ".git".
```bash
$ git init
```
### config
To configure settings. Whether it be for the repository, the system itself, or global
configurations.
```bash
# Print & Set Some Basic Config Variables (Global)
$ git config --global user.email
$ git config --global user.name
$ git config --global user.email "MyEmail@Zoho.com"
$ git config --global user.name "My Name"
```
[Learn More About git config.](http://git-scm.com/docs/git-config)
### help
To give you quick access to an extremely detailed guide of each command. Or to
just give you a quick reminder of some semantics.
```bash
# Quickly check available commands
$ git help
# Check all available commands
$ git help -a
# Command specific help - user manual
# git help <command_here>
$ git help add
$ git help commit
$ git help init
```
### status
To show differences between the index file (basically your working copy/repo) and the current
HEAD commit.
```bash
# Will display the branch, untracked files, changes and other differences
$ git status
# To learn other "tid bits" about git status
$ git help status
```
### add
To add files to the current working tree/directory/repo. If you do not `git add` new files to the
working tree/directory, they will not be included in commits!
```bash
# add a file in your current working directory
$ git add HelloWorld.java
# add a file in a nested dir
$ git add /path/to/file/HelloWorld.c
# Regular Expression support!
$ git add ./*.java
```
### branch
Manage your branches. You can view, edit, create, delete branches using this command.
```bash
# list existing branches & remotes
$ git branch -a
# create a new branch
$ git branch myNewBranch
# delete a branch
$ git branch -d myBranch
# rename a branch
# git branch -m <oldname> <newname>
$ git branch -m myBranchName myNewBranchName
# edit a branch's description
$ git branch myBranchName --edit-description
```
### checkout
Updates all files in the working tree to match the version in the index, or specified tree.
```bash
# Checkout a repo - defaults to master branch
$ git checkout
# Checkout a specified branch
$ git checkout branchName
# Create a new branch & switch to it, like: "git branch <name>; git checkout <name>"
$ git checkout -b newBranch
```
### clone
Clones, or copies, an existing repository into a new directory. It also adds
remote-tracking branches for each branch in the cloned repo, which allows you to push
to a remote branch.
```bash
# Clone learnxinyminutes-docs
$ git clone https://github.com/adambard/learnxinyminutes-docs.git
```
### commit
Stores the current contents of the index in a new "commit." This commit contains
the changes made and a message created by the user.
```bash
# commit with a message
$ git commit -m "Added multiplyNumbers() function to HelloWorld.c"
# automatically stage modified or deleted files, except new files, and then commit
$ git commit -a -m "Modified foo.php and removed bar.php"
```
### diff
Shows differences between a file in the working directory, index and commits.
```bash
# Show difference between your working dir and the index
$ git diff
# Show differences between the index and the most recent commit.
$ git diff --cached
# Show differences between your working dir and the most recent commit
$ git diff HEAD
```
### grep
Allows you to quickly search a repository.
Optional Configurations:
```bash
# Thanks to Travis Jeffery for these
# Set line numbers to be shown in grep search results
$ git config --global grep.lineNumber true
# Make search results more readable, including grouping
$ git config --global alias.g "grep --break --heading --line-number"
```
```bash
# Search for "variableName" in all java files
$ git grep 'variableName' -- '*.java'
# Search for a line that contains "arrayListName" and, "add" or "remove"
$ git grep -e 'arrayListName' --and \( -e add -e remove \)
```
Google is your friend; for more examples
[Git Grep Ninja](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja)
### log
Display commits to the repository.
```bash
# Show all commits
$ git log
# Show X number of commits
$ git log -n 10
# Show merge commits only
$ git log --merges
```
### merge
"Merge" in changes from external commits into the current branch.
```bash
# Merge the specified branch into the current.
$ git merge branchName
# Always generate a merge commit when merging
$ git merge --no-ff branchName
```
### mv
Rename or move a file
```bash
# Renaming a file
$ git mv HelloWorld.c HelloNewWorld.c
# Moving a file
$ git mv HelloWorld.c ./new/path/HelloWorld.c
# Force rename or move
# "existingFile" already exists in the directory, will be overwritten
$ git mv -f myFile existingFile
```
### pull
Pulls from a repository and merges it with another branch.
```bash
# Update your local repo, by merging in new changes
# from the remote "origin" and "master" branch.
# git pull <remote> <branch>
# git pull => implicitly defaults to => git pull origin master
$ git pull origin master
# Merge in changes from remote branch and rebase
# branch commits onto your local repo, like: "git pull <remote> <branch>, git rebase <branch>"
$ git pull origin master --rebase
```
### push
Push and merge changes from a branch to a remote & branch.
```bash
# Push and merge changes from a local repo to a
# remote named "origin" and "master" branch.
# git push <remote> <branch>
# git push => implicitly defaults to => git push origin master
$ git push origin master
# To link up current local branch with a remote branch, add -u flag:
$ git push -u origin master
# Now, anytime you want to push from that same local branch, use shortcut:
$ git push
```
### stash
Stashing takes the dirty state of your working directory and saves it on a stack of unfinished changes that you can reapply at any time.
Let's say you've been doing some work in your git repo, but you want to pull from the remote.
Since you have dirty (uncommited) changes to some files, you are not able to run `git pull`.
Instead, you can run `git stash` to save your changes onto a stack!
```bash
$ git stash
Saved working directory and index state \
"WIP on master: 049d078 added the index file"
HEAD is now at 049d078 added the index file
(To restore them type "git stash apply")
```
Now you can pull!
```bash
git pull
```
`...changes apply...`
Now check that everything is OK
```bash
$ git status
# On branch master
nothing to commit, working directory clean
```
You can see what "hunks" you've stashed so far using `git stash list`.
Since the "hunks" are stored in a Last-In-First-Out stack, our most recent change will be at top.
```bash
$ git stash list
stash@{0}: WIP on master: 049d078 added the index file
stash@{1}: WIP on master: c264051 Revert "added file_size"
stash@{2}: WIP on master: 21d80a5 added number to log
```
Now let's apply our dirty changes back by popping them off the stack.
```bash
$ git stash pop
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
#
# modified: index.html
# modified: lib/simplegit.rb
#
```
`git stash apply` does the same thing
Now you're ready to get back to work on your stuff!
[Additional Reading.](http://git-scm.com/book/en/v1/Git-Tools-Stashing)
### rebase (caution)
Take all changes that were committed on one branch, and replay them onto another branch.
*Do not rebase commits that you have pushed to a public repo*.
```bash
# Rebase experimentBranch onto master
# git rebase <basebranch> <topicbranch>
$ git rebase master experimentBranch
```
[Additional Reading.](http://git-scm.com/book/en/Git-Branching-Rebasing)
### reset (caution)
Reset the current HEAD to the specified state. This allows you to undo merges,
pulls, commits, adds, and more. It's a great command but also dangerous if you don't
know what you are doing.
```bash
# Reset the staging area, to match the latest commit (leaves dir unchanged)
$ git reset
# Reset the staging area, to match the latest commit, and overwrite working dir
$ git reset --hard
# Moves the current branch tip to the specified commit (leaves dir unchanged)
# all changes still exist in the directory.
$ git reset 31f2bb1
# Moves the current branch tip backward to the specified commit
# and makes the working dir match (deletes uncommited changes and all commits
# after the specified commit).
$ git reset --hard 31f2bb1
```
### rm
The opposite of git add, git rm removes files from the current working tree.
```bash
# remove HelloWorld.c
$ git rm HelloWorld.c
# Remove a file from a nested dir
$ git rm /pather/to/the/file/HelloWorld.c
```
## Further Information
* [tryGit - A fun interactive way to learn Git.](http://try.github.io/levels/1/challenges/1)
* [git-scm - Video Tutorials](http://git-scm.com/videos)
* [git-scm - Documentation](http://git-scm.com/docs)
* [Atlassian Git - Tutorials & Workflows](https://www.atlassian.com/git/)
* [SalesForce Cheat Sheet](https://na1.salesforce.com/help/doc/en/salesforce_git_developer_cheatsheet.pdf)
* [GitGuys](http://www.gitguys.com/)
* [Git - the simple guide](http://rogerdudler.github.io/git-guide/index.html)
|