Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.
$ git config --global user.name "Lorem Ipsum"
$ git config --global user.email lorem@ips.um
$ git config --global color.ui true
gitk
, git-gui
Thank you, thank you. Let's get started. Max, play me over.
(gasps) Looks like someone forgot to feed Max!
git init
~/ikdoeict/git-demo
$ git init
Initialized empty Git repository in /Users/roelvs/git-demo/.git/
~/ikdoeict/git-demo
$
.git
folder containing
git status
to check
~/ikdoeict/git-demo
$ touch test.txt
$ ~/ikdoeict/git-demo
$ git status
# …
#
# Untracked files:
# …
# test.txt
#
git add
→ staginggit commit
→ committing
~/ikdoeict/git-demo
$ git add test.txt
~/ikdoeict/git-demo
$ git commit -m 'Start tracking test.txt'
[main (root-commit) 9c43f96] Start tracking test.txt
0 files changed
create mode 100644 test.txt
test.txt
is stored in the repository
9c43f96
~/ikdoeict/git-demo on main
$ touch test2.txt
~/ikdoeict/git-demo on main
$ echo 'hello' >> test.txt
~/ikdoeict/git-demo on main*
$ git status
# On branch main
# Changes not staged for commit:
# …
# modified: test.txt
#
# Untracked files:
# …
# test2.txt
#
~/ikdoeict/git-demo on main*
$ git add test2.txt
~/ikdoeict/git-demo on main*
$ git status
# On branch main
# Changes to be committed:
# …
# new file: test2.txt
#
# Changes not staged for commit:
# …
# modified: test.txt
#
~/ikdoeict/git-demo on main*
$ git commit -m 'Start tracking test2'
[main f1c6883] Start tracking test2
0 files changed
create mode 100644 test2.txt
~/ikdoeict/git-demo on main*
$ git status
# On branch main
# Changes not staged for commit:
# …
# modified: test.txt
#
$ git commit -am 'commitmessage'
$ git commit --amend -m 'commitmessage'
$ git add .
.txt
files
$ git add *.txt
$ git add subfolder/
$ git reset filename
~/ikdoeict/git-demo on main
$ rm test2.txt
~/ikdoeict/git-demo on main
$ git status
# On branch main
# Changes not staged for commit:
#
# modified: test.txt
# deleted: test2.txt
#
~/ikdoeict/git-demo on main*
$ git add .
~/ikdoeict/git-demo on main*
$ git status
# On branch main
# Changes to be committed:
# …
# modified: test.txt
#
# Changes not staged for commit:
# …
# deleted: test2.txt
#
~/ikdoeict/git-demo on main*
$ git add -u .
~/ikdoeict/git-demo on main*
$ git status
# On branch main
# Changes to be committed:
# …
# modified: test.txt
# deleted: test2.txt
#
#
~/ikdoeict/git-demo on main*
$ git reset test.txt
Unstaged changes after reset:
M test.txt
~/ikdoeict/git-demo on main*
$ git commit -m 'Deleted test2.txt'
[main 1d7a184] Deleted test2.txt
0 files changed
delete mode 100644 test2.txt
~/ikdoeict/git-demo on main*
$ git status
# On branch main
# Changes not staged for commit:
# …
# modified: test.txt
#
#
~/ikdoeict/git-demo on main*
$ ls
drwxr-xr-x 4 roelvs staff 136 Mar 19 21:18 .
drwxr-xr-x 10 roelvs staff 340 Mar 19 15:49 ..
drwxr-xr-x 13 roelvs staff 442 Mar 19 21:24 .git
-rw-r--r-- 1 roelvs staff 6 Mar 19 20:44 test.txt
~/ikdoeict/git-demo on main*
$ git commit -am 'Hello'
[main c53f9b6] Hello
1 file changed, 1 insertion(+)
~/ikdoeict/git-demo on main
$
git add -u
git rm file
git diff file
to compare the current state with the previously committed state
~/ikdoeict/git-demo on main
$ echo 'more hello' >> test.txt
~/ikdoeict/git-demo on main*
$ git diff test.txt
diff --git a/test.txt b/test.txt
index ce01362..3477282 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1,2 @@
hello
+more hello
git log
to see the commit log
~/ikdoeict/git-demo
$ git log
commit c53f9b6bd0e7271af7c5d856f84f51d9b749d77f
Author: roelvs <roelvs@bram.us>
Date: Tue Mar 19 22:09:32 2013 +0100
Hello
commit 1d7a18481b5f6664d2cf30b1455c6ad1c041caa2
Author: roelvs <roelvs@bram.us>
Date: Tue Mar 19 21:24:13 2013 +0100
Deleted test2.txt
commit f1c68836b8c1f91c16d4f4c0540fca0f251ff946
Author: roelvs <roelvs@bram.us>
Date: Tue Mar 19 20:44:31 2013 +0100
Start tracking test2
commit 9c43f961b1defcc2f4f14526a2b20c4f3c267a62
Author: roelvs <roelvs@bram.us>
Date: Tue Mar 19 16:02:03 2013 +0100
Start tracking test.txt
q
to exit the commit loggit log --oneline
to get a concise output
~/ikdoeict/git-demo
$ git log --oneline
c53f9b6 Hello
1d7a184 deleted test2.txt
f1c6883 Start tracking test2
9c43f96 Start tracking test.txt
~/ikdoeict/git-demo
$
$ git log --author=name
$ git log --since="1 week ago"
git log
$ git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
~/ikdoeict/git-demo
$ git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
* c53f9b6 - (HEAD, main) Hello (16 minutes ago) <roelvs>
* 1d7a184 - Deleted test2.txt (61 minutes ago) <roelvs>
* f1c6883 - Start tracking test2 (2 hours ago) <roelvs>
* 9c43f96 - Start tracking test.txt (6 hours ago) <roelvs>
git lg
for it
$ git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
git lg
to get the output as shown above$ git init
$ git add file
$ git reset file
$ git commit -m 'message'
$ git diff file
$ git lg
Welcome to the Head Museum. I'm Leonard Nimoy.
~/ikdoeict/git-demo on main
$ git lg
* c53f9b6 - (HEAD, main) Hello (15 hours ago) <roelvs>
* 1d7a184 - Deleted test2.txt (16 hours ago) <roelvs>
* f1c6883 - Start tracking test2 (17 hours ago) <roelvs>
* 9c43f96 - Start tracking test.txt (22 hours ago) <roelvs>
~/ikdoeict/git-demo on main
$ git checkout 1d7a184
Note: checking out '1d7a184'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
HEAD is now at 1d7a184... Deleted test2.txt
~/ikdoeict/git-demo on (no branch)
$ git lg
* 1d7a184 - (HEAD) Deleted test2.txt (16 hours ago) <roelvs>
* f1c6883 - Start tracking test2 (17 hours ago) <roelvs>
* 9c43f96 - Start tracking test.txt (22 hours ago) <roelvs>
~/ikdoeict/git-demo on main
$ git checkout f1c6883
Previous HEAD position was 1d7a184... Deleted test2.txt
HEAD is now at f1c6883... Start tracking test2
~/ikdoeict/git-demo on (no branch)
$ git lg
* f1c6883 - (HEAD) Start tracking test2 (17 hours ago) <roelvs>
* 9c43f96 - Start tracking test.txt (22 hours ago) <roelvs>
~/ikdoeict/git-demo on main
$ git checkout main
Previous HEAD position was f1c6883... Start tracking test2
Switched to branch 'main'
~/ikdoeict/git-demo on main
$ git lg
* c53f9b6 - (HEAD, main) Hello (15 hours ago) <roelvs>
* 1d7a184 - Deleted test2.txt (16 hours ago) <roelvs>
* f1c6883 - Start tracking test2 (17 hours ago) <roelvs>
* 9c43f96 - Start tracking test.txt (22 hours ago) <roelvs>
~/ikdoeict/git-demo on main
$
HEAD
using git checkout
$ git reset filename
$ git reset HEAD
$ git checkout -- filename
$ git reset HEAD --hard
$ git stash
Well, let's at least throw this TV away,
the batteries in the remote are gettin low.
git clone url
~/ikdoeict
$ git clone git@github.com:fabpot/Silex.git
Cloning into 'Silex'...
remote: Counting objects: 6612, done.
remote: Compressing objects: 100% (1908/1908), done.
remote: Total 6612 (delta 4225), reused 6317 (delta 4008)
Receiving objects: 100% (6612/6612), 1.28 MiB | 176 KiB/s, done.
Resolving deltas: 100% (4225/4225), done.
~/ikdoeict
$ cd Silex
~/ikdoeict/Silex on main
$ git log --oneline
59e7dbd merged branch davedevelopment/add-doc-info-to-docs (PR #647)
6a4fffe Added a note about writing documentation
8e6d30a merged branch davedevelopment/form-extension-points (PR #553)
7c38c9a Add services allowing for form type extensions and guessers
fd3ba62 merged branch GromNaN/remember-me (PR #645)
adc172b Add support for remember-me with RememberMeServiceProvider
fcd93b3 added a note about all possible options for the session (refs #633)
a31…
…
git clone url .
git remote add name url
~/ikdoeict/git-demo on main
$ git remote add origin git@github.com:roelvs/git-demo.git
~/ikdoeict/git-demo on main
$ git push origin main
Counting objects: 9, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (9/9), 705 bytes, done.
Total 9 (delta 1), reused 0 (delta 0)
To git@github.com:roelvs/git-demo.git
* [new branch] main -> main
~/ikdoeict/git-demo on main
$
$ git push origin main
git push
and it'll default to origin
and main
$ git pull
origin/main
→ main
~/ikdoeict/git-demo on main
$ git remote show
origin
~/ikdoeict/git-demo on main
$ git remote show origin
* remote origin
Fetch URL: git@github.com:roelvs/git-demo.git
Push URL: git@github.com:roelvs/git-demo.git
HEAD branch: main
Remote branch:
main tracked
Local ref configured for 'git push':
main pushes to main (up to date)
Imagine that this line represents time. At some point in the past, the timeline skewed into this tangent creating an alternate 1985.
main
$ git branch
$ git branch experimental
$ git checkout experimental
head
will be moved to the new branchexperiment
branch based on the main
~/ikdoeict/git-demo on main
$ git branch
* main
~/ikdoeict/git-demo on main
$ git branch experiment
~/ikdoeict/git-demo on main
$ git branch
experiment
* main
~/ikdoeict/git-demo on main
$ git checkout experiment
Switched to branch 'experiment'
~/ikdoeict/git-demo on experiment
$ git branch
* experiment
main
~/ikdoeict/git-demo on experiment
$ touch exp.txt
~/ikdoeict/git-demo on experiment*
$ git add .
~/ikdoeict/git-demo on experiment*
$ git commit -m 'Start tracking exp.txt'
[experiment a65b9d7] Start tracking exp.txt
0 files changed
create mode 100644 exp.txt
~/ikdoeict/git-demo on experiment
$ git lg
* a65b9d7 - (HEAD, experiment) Start tracking exp.txt (7 seconds ago) <roelvs>
* c53f9b6 - (origin/main, main) Hello (15 hours ago) <roelvs>
* 1d7a184 - Deleted test2.txt (16 hours ago) <roelvs>
* f1c6883 - Start tracking test2 (17 hours ago) <roelvs>
* 9c43f96 - Start tracking test.txt (22 hours ago) <roelvs>
~/ikdoeict/git-demo on experiment
$ git checkout main
Switched to branch 'main'
~/ikdoeict/git-demo on main
$ ls
drwxr-xr-x 4 roelvs staff 136 Mar 20 20:19 .
drwxr-xr-x 11 roelvs staff 374 Mar 20 15:53 ..
drwxr-xr-x 14 roelvs staff 476 Mar 20 20:19 .git
-rw-r--r-- 1 roelvs staff 6 Mar 20 14:38 test.txt
~/ikdoeict/git-demo on main
$ echo 'on the main right now' >> test.txt
~/ikdoeict/git-demo on main*
$ git add .
~/ikdoeict/git-demo on main*
$ git commit -m 'on the main'
[main 0ea8dd4] on the main
1 file changed, 1 insertion(+)
~/ikdoeict/git-demo on main
$ git lg
* 0ea8dd4 - (HEAD, main) on the main (2 seconds ago) <roelvs>
* c53f9b6 - (origin/main) Hello (15 hours ago) <roelvs>
* 1d7a184 - Deleted test2.txt (16 hours ago) <roelvs>
* f1c6883 - Start tracking test2 (17 hours ago) <roelvs>
* 9c43f96 - Start tracking test.txt (22 hours ago) <roelvs>
git merge
otherbranch
are merged into the HEAD
~/ikdoeict/git-demo on main
$ git merge experiment
Merge made by the 'recursive' strategy.
0 files changed
create mode 100644 exp.txt
~/ikdoeict/git-demo on main
$ git lg
* 965d016 - (HEAD, main) Merge branch 'experiment' (5 seconds ago) <roelvs>
|\
| * a65b9d7 - (experiment) Start tracking exp.txt (6 minutes ago) <roelvs>
* | 0ea8dd4 - on the main (2 minutes ago) <roelvs>
|/
* c53f9b6 - (origin/main) Hello (22 hours ago) <roelvs>
* 1d7a184 - Deleted test2.txt (23 hours ago) <roelvs>
* f1c6883 - Start tracking test2 (24 hours ago) <roelvs>
* 9c43f96 - Start tracking test.txt (28 hours ago) <roelvs>
$ git branch -d branchname
-D
instead of -d
~/ikdoeict/git-demo on main
$ git branch -d otherbranch
error: The branch 'otherbranch' is not fully merged.
If you are sure you want to delete it, run 'git branch -D otherbranch'.
~/ikdoeict/git-demo on main
$ git branch -D otherbranch
Deleted branch otherbranch (was e079840).
Hold tight!
~/ikdoeict/git-demo on main
$ echo 'something for exp' >> exp.txt
~/ikdoeict/git-demo on main*
$ git add .
~/ikdoeict/git-demo on main*
$ git commit -m 'change exp.txt'
[main babbcd3] change exp.txt
1 file changed, 1 insertion(+)
~/ikdoeict/git-demo on main
$ git checkout experiment
Switched to branch 'experiment'
~/ikdoeict/git-demo on experiment
$ echo 'a different line for exp.txt' >> exp.txt
~/ikdoeict/git-demo on experiment*
$ git add .
~/ikdoeict/git-demo on experiment*
$ git commit -m 'change exp.txt (from experiment)'
[experiment 2925064] change exp.txt (from experiment)
1 file changed, 1 insertion(+)
~/ikdoeict/git-demo on experiment
$ git checkout main
Switched to branch 'main'
~/ikdoeict/git-demo on main
$ git merge experiment
Auto-merging exp.txt
CONFLICT (content): Merge conflict in exp.txt
Automatic merge failed; fix conflicts and then commit the result.
~/ikdoeict/git-demo on main*
$ git status
# On branch main
# Unmerged paths:
# (use "git add/rm <file>..." as appropriate to mark resolution)
#
# both modified: exp.txt
#
~/ikdoeict/git-demo on main*
$ cat exp.txt
<<<<<<< HEAD
something for exp
=======
a different line for exp.txt
>>>>>>> experiment
~/ikdoeict/git-demo on main*
$ subl exp.txt
~/ikdoeict/git-demo on main*
$ git add exp.txt
~/ikdoeict/git-demo on main*
$ git commit
[main 80de07c] Merge branch 'experiment'
~/ikdoeict/git-demo on main
$
<<<<<<< HEAD
something for exp
=======
a different line for exp.txt
>>>>>>> experiment
HEAD
$ git checkout --ours conflictedfile
otherbranch
$ git checkout --theirs conflictedfile
featurebranch
is completed, merge it into the main
~/ikdoeict/git-demo on main
$ git lg
* 1e7f02e - (HEAD, main) A change comtd on main (12 seconds ago) <roelvs>
* 80de07c - First commit! (2 minutes ago) <roelvs>
~/ikdoeict/git-demo on main
$ git checkout experiment
Switched to branch 'experiment'
~/ikdoeict/git-demo on experiment
$ git lg
* 669ae62 - (HEAD, experiment) A 2nd change comtd on experiment (34 seconds ago) <roelvs>* a9bdacb - A change comtd on experiment(69 seconds ago) <roelvs>
* 80de07c - First commit! (2 minutes ago) <roelvs>
~/ikdoeict/git-demo on experiment
$ git rebase main
First, rewinding head to replay your work on top of it...
Applying: A change comtd on experiment
Applying: A 2nd change comtd on experiment
~/ikdoeict/git-demo on experiment
$ git lg
* dba0673 - (HEAD, experiment) A 2nd change comtd on experiment (2 seconds ago) <roelvs>* 84484e4 - A change comtd on experiment(2 seconds ago) <roelvs>
* 1e7f02e - (main) A change comtd on main (54 seconds ago) <roelvs>
* 80de07c - First commit! (3 minutes ago) <roelvs>
Note: New commit hashes are generated as the patches are applied on top of the rewind/ffwd!
git rebase
git rebase
$ git add conflictedfile
$ git rebase --continue
$ git rebase --abort
$ git push origin localbranch:remotebranch
$ git push origin :remotebranch
$ git checkout -b localbranch remote/remotebranch
$ git remote update
Yes, we have to work together, and not
have this fight I was definitely winning.
# 1. Make sure the main is up-to-date
$ git checkout main
$ git pull
# 2. Create a featurebranch based on the main
$ git checkout -b featurebranch
# 3. Develop, stage, and commit your feature on the featurebranch.
When finished continue to step 4
# 4. Make sure the main is still up-to-date
$ git checkout main
$ git pull
# 5. Rebase the main onto the featurebranch
(skip this step if main remained unchanged since step 1)
$ git checkout featurebranch
$ git rebase main
# 6. Merge the featurebranch onto the main
$ git checkout main
$ git merge featurebranch
# 7. Push the main
$ git push origin main
# 8. Clean up
$ git branch -d featurebranch
# 9. Rinse. Repeat
main
, but on featurebranches
git pull --rebase
to minimize the situation and keep the main clean (#). From then on create a featurebranch and continuemain
must at all times contain deployable code $ git revert HEAD~1
$ git rebase -i commithash
$ git rebase -i HEAD~2
PLEASE NOTE: GITHUB/GITLAB IS NOT GIT!
AGAIN: GITHUB/GITLAB IS NOT GIT!
If you don't like my code, Fork off!
featurebranch
featurebranch
when ready to your own GitHub remote
# 1. Create a fork on GitHub
e.g. clone fabpot/Silex to roelvs/Silex
# 2. Clone your repo locally
$ git clone git@github.com:roelvs/Silex.git
# 3. Create a featurebranch based on the main
$ git checkout -b featurebranch
# 4. Develop, stage, and commit your feature on the featurebranch.
When finished continue to step 5
# 5. Publish your featurebranch on GitHub
$ git push origin localbranch remotebranch
# 6. Do a pull request via GitHub and await merging
# 7. Rinse. Repeat.
Make sure your main is in sync with the original main one!
(add the original repo as remote and `git fetch` and `git rebase original/main`)
Or, alternatively, do it via the Github website ;-)
# 1. Checkout your main branch
$ git checkout main
# 2. Add a new remote named 'otherdude'
$ git remote add otherdude git://github.com/otherdude/Project.git
# 3. Fetch information about all branches on the 'otherdude' remote
$ git fetch otherdude
# 4. Merge 'otherdude/featurebranch' into your main
$ git merge otherdude/featurebranch
# 5. Push your newly-merged branch back to GitHub
$ git push origin main
Or, alternatively, do it via the GitHub website ;-)
Let's go. If I say one more thing,
I might say it with my evening boot.
.gitignore
Thumbs.db
app.db
*.log
vendor/*
node_modules/*
config.php
.gitignore
must be committed into the repository
config.php
config.php
to .gitignore
and provide a config.sample.php
instead
Don't believe me? Check Leaked credentials on GitHub.
git add -p file
~/ikdoeict/ikdoeict-website on main*
$ git add -p index.html
diff --git a/index.html b/index.html
index 3fc8413..d7af84e 100644
--- a/index.html
+++ b/index.html
@@ -1,6 +1,6 @@
<!DOCTYPE html>
<head>
- <title>Home | Ikdoeict.BE</title>
+ <title>Home | IkdoeICT.BE</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="css/normalize.css" />
Stage this hunk [y,n,q,a,d,/,j,J,g,e,?]? y
@@ -176,7 +176,7 @@
</section>
<footer>
- <p>Copyright (c) 2021 IkdoeICT.be</p>
+ <p>Copyright (c) 2022 IkdoeICT.be</p>
</footer>
</div>
Stage this hunk [y,n,q,a,d,/,j,J,g,e,?]? n
~/ikdoeict/ikdoeict-website on main*
$ git status
# On branch main
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: index.html
#
# 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: index.html
#
~/ikdoeict/ikdoeict-website on main*
$ git commit -m 'title casing'
[main fc91e11] title casing
1 file changed, 1 insertion(+), 1 deletion(-)
~/ikdoeict/ikdoeict-website on main*
$ git diff index.html
diff --git a/index.html b/index.html
index 7602651..d7af84e 100644
--- a/index.html
+++ b/index.html
@@ -176,7 +176,7 @@
</section>
<footer>
- <p>Copyright (c) 2021 IkdoeICT.be</p>
+ <p>Copyright (c) 2022 IkdoeICT.be</p>
</footer>
</div>
~/ikdoeict/ikdoeict-website on main*
$ git add .
~/ikdoeict/ikdoeict-website on main*
$ git commit -m 'copyright 2022 instead of 2021'
[main c36c7be] copyright 2022 instead of 2021
1 file changed, 1 insertion(+), 1 deletion(-)
(Press ↓ to see some frequently asked ones)