Programutveckling med Git

En introduktion

Most images in this presentation are from the Pro Git book. The entire Pro Git book, written by Scott Chacon and Ben Straub and published by Apress, is available here. All content is licensed under the Creative Commons Attribution Non Commercial Share Alike 3.0 license. Print versions of the book are available on Amazon.com.

Some images are from Git With The Program: Introduction to Basic Git Concepts - Drupal Camp LA 2013. All content is licensed under the CC Attribution-ShareAlike License.

Why Git

  • Share information with others and/or yourself
  • Work with multiple things at the same time
  • Backup
  • Test stuff quick and easy
  • So many projects are using Git

In [1]:
from IPython.core.display import HTML
HTML('<iframe width="560" height="315" src="https://www.youtube.com/embed/pOSqctHH9vY" frameborder="0" allowfullscreen></iframe>')


Out[1]:

Version Control Systems

To mention a few:

  • Centralized Version Control Systems
    • Git
    • Mercurial
  • Distributed Version Control Systems
    • SCCS
    • RCS
    • CVS
    • PVCS
    • SourceTree
    • TFS
    • Perforce
Centralized Distributed
<img src="centralized.png", width=600> <img src="distributed.png", width=600>

Git concepts

Stream of snapshots

<img src="snapshots.png", width=600>

List of file-based changes

<img src="deltas.png", width=600>

Data Model

  • Blobs (atual data)
  • Tree (directories of blobs or of other trees)
  • A commit
    • A tree
    • Zero or more parent commits
    • Meta data (message, email, timestamp) <img src="data-model-2.png", width=600>

SHA1

<img src="sha1.jpg", width=300>

The Three States

<img src="areas.png", width=600>

Let's get started

Initialize a local repository


In [2]:
%%bash
cd /tmp
rm -rf TickProject
mkdir TickProject
cd TickProject
git init
tree -aC


Initialized empty Git repository in /private/tmp/TickProject/.git/
.
└── .git
    ├── HEAD
    ├── config
    ├── description
    ├── hooks
    │   ├── applypatch-msg.sample
    │   ├── commit-msg.sample
    │   ├── post-update.sample
    │   ├── pre-applypatch.sample
    │   ├── pre-commit.sample
    │   ├── pre-push.sample
    │   ├── pre-rebase.sample
    │   ├── pre-receive.sample
    │   ├── prepare-commit-msg.sample
    │   └── update.sample
    ├── info
    │   └── exclude
    ├── objects
    │   ├── info
    │   └── pack
    └── refs
        ├── heads
        └── tags

9 directories, 14 files

Write some code and check status


In [3]:
%%bash
. quickedit v0.1
# git archive --format=tar --prefix=src/ --remote=~/src/maker-presentation $TAG:TickCounter | tar xf -
tree -aCI .git
git status


.
└── src
    ├── KeyTicker.h
    ├── TickerInterface.h
    └── main.cpp

1 directory, 3 files
On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	src/

nothing added to commit but untracked files present (use "git add" to track)

Add code to stage area and check status


In [4]:
%%bash
cd /tmp/TickProject
git add .
git status


On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

	new file:   src/KeyTicker.h
	new file:   src/TickerInterface.h
	new file:   src/main.cpp

Transfer code to local repository


In [5]:
%%bash
cd /tmp/TickProject
git commit -a -m "Initial revision"
git status


[master (root-commit) 19b738a] Initial revision
 3 files changed, 109 insertions(+)
 create mode 100644 src/KeyTicker.h
 create mode 100644 src/TickerInterface.h
 create mode 100644 src/main.cpp
On branch master
nothing to commit, working tree clean

Some Git clients

Write some more code (change name of a variable and add a meson.build file)

Use a gui client to see status and commit code


In [6]:
!. quickedit v0.2

Build and check status

  • Meson is a build generating system
  • Ninja is a small build system with a focus on speed.

In [7]:
%%bash
cd /tmp/TickProject && rm -rf build
meson src build


The Meson build system
Version: 0.39.1
Source dir: /private/tmp/TickProject/src
Build dir: /private/tmp/TickProject/build
Build type: native build
Project name: TickCounterProject
Native cpp compiler: c++ (clang 8.1.0)
Build machine cpu family: x86_64
Build machine cpu: x86_64
Dependency threads found: YES
Build targets in project: 1

In [8]:
%%bash
ninja -C /tmp/TickProject/build


ninja: Entering directory `/tmp/TickProject/build'
[1/2] Compiling cpp object 'tickcounter@exe/main.cpp.o'
[2/2] Linking target tickcounter
clang: warning: argument unused during compilation: '-pthread' [-Wunused-command-line-argument]

In [9]:
%%bash
cd /tmp/TickProject
git status


On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

	build/

nothing added to commit but untracked files present (use "git add" to track)

Instruct Git to ignore build artifacts and other files that shouldn't be version controlled

Add an .gitignore file There are plenty of examples of .gitignore files on the net and/or use e.g., https://www.gitignore.io


In [10]:
%%bash
cd /tmp/TickProject
git status


On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

	.gitignore

nothing added to commit but untracked files present (use "git add" to track)

Branches, HEAD and tags?

<img src="branch-and-history.png", width=600>


In [11]:
%%bash
cd /tmp/TickProject
git branch -v


* master 6845752 Initial revision

Creating a New Branch <img src="two-branches.png", width=600>

HEAD pointing to a branch <img src="head-to-master.png", width=600>

Switching Branch <img src="head-to-testing.png", width=600>

The HEAD branch moves forward when a commit is made <img src="advance-testing.png", width=600>

HEAD moves when you checkout <img src="checkout-master.png", width=600>

Third party package usage strategies

  • Package Manager
    • Homebrew
    • Nuget
    • apt-get
  • Git submodules / subtrees
    • Qt
  • In source
  • Separate repositories (pkg-config)

Add better logging support to our TickCounter project

Let's use the 3rd party spdlog package as a separate repository and try it out in a logging feature branch

https://github.com/gabime/spdlog.git

Get the spdlog repo


In [12]:
%%bash
cd /tmp
rm -rf spdlog
rm -rf 3rd/spdlog
git clone https://github.com/gabime/spdlog.git spdlog


Cloning into 'spdlog'...

In [13]:
%%bash
cd /tmp/spdlog
ls -la


total 32
drwxr-xr-x  15 tommy  wheel   510 Apr 30 19:33 .
drwxrwxrwt  14 root   wheel   476 Apr 30 19:33 ..
drwxr-xr-x  12 tommy  wheel   408 Apr 30 19:33 .git
-rw-r--r--   1 tommy  wheel   779 Apr 30 19:33 .gitignore
-rw-r--r--   1 tommy  wheel  3518 Apr 30 19:33 .travis.yml
-rw-r--r--   1 tommy  wheel  2418 Apr 30 19:33 CMakeLists.txt
-rw-r--r--   1 tommy  wheel   323 Apr 30 19:33 INSTALL
-rw-r--r--   1 tommy  wheel  1142 Apr 30 19:33 LICENSE
-rw-r--r--   1 tommy  wheel  7656 Apr 30 19:33 README.md
-rwxr-xr-x   1 tommy  wheel   129 Apr 30 19:33 astyle.sh
drwxr-xr-x  19 tommy  wheel   646 Apr 30 19:33 bench
drwxr-xr-x   4 tommy  wheel   136 Apr 30 19:33 cmake
drwxr-xr-x  14 tommy  wheel   476 Apr 30 19:33 example
drwxr-xr-x   3 tommy  wheel   102 Apr 30 19:33 include
drwxr-xr-x  18 tommy  wheel   612 Apr 30 19:33 tests

CMake is used in spdlog! A commonly used build preparing tool.

Build and install spdlog

Try it out in cmake gui


In [14]:
%%bash
cd /tmp/spdlog-build
ls -l


total 24
-rw-r--r--   1 tommy  wheel  16159 Apr 30 19:34 CMakeCache.txt
drwxr-xr-x  11 tommy  wheel    374 Apr 30 19:34 CMakeFiles
drwxr-xr-x  15 tommy  wheel    510 Apr 30 19:34 CMakeScripts
-rw-r--r--   1 tommy  wheel   2776 Apr 30 19:33 DartConfiguration.tcl
drwxr-xr-x   3 tommy  wheel    102 Apr 30 19:33 Testing
-rw-r--r--   1 tommy  wheel   2544 Apr 30 19:34 cmake_install.cmake
drwxr-xr-x   5 tommy  wheel    170 Apr 30 19:34 generated
drwxr-xr-x   3 tommy  wheel    102 Apr 30 19:34 spdlog.xcodeproj
drwxr-xr-x   4 tommy  wheel    136 Apr 30 19:33 tests

In [15]:
%%bash
cd /tmp/spdlog-build
xcodebuild -configuration Release -target install


=== BUILD AGGREGATE TARGET ZERO_CHECK OF PROJECT spdlog WITH CONFIGURATION Release ===

Check dependencies

Write auxiliary files
write-file /tmp/spdlog-build/spdlog.build/Release/ZERO_CHECK.build/Script-E5A697B66AFA4CA9A63FC2F7.sh
chmod 0755 /tmp/spdlog-build/spdlog.build/Release/ZERO_CHECK.build/Script-E5A697B66AFA4CA9A63FC2F7.sh

PhaseScriptExecution CMake\ Rules /tmp/spdlog-build/spdlog.build/Release/ZERO_CHECK.build/Script-E5A697B66AFA4CA9A63FC2F7.sh
    cd /tmp/spdlog
    /bin/sh -c /tmp/spdlog-build/spdlog.build/Release/ZERO_CHECK.build/Script-E5A697B66AFA4CA9A63FC2F7.sh
echo ""

make -f /tmp/spdlog-build/CMakeScripts/ReRunCMake.make
make[1]: `/private/tmp/spdlog-build/CMakeFiles/cmake.check_cache' is up to date.

=== BUILD AGGREGATE TARGET ALL_BUILD OF PROJECT spdlog WITH CONFIGURATION Release ===

Check dependencies

Write auxiliary files
write-file /tmp/spdlog-build/spdlog.build/Release/ALL_BUILD.build/Script-C239D05C9752437B977BDA30.sh
chmod 0755 /tmp/spdlog-build/spdlog.build/Release/ALL_BUILD.build/Script-C239D05C9752437B977BDA30.sh

PhaseScriptExecution CMake\ Rules /tmp/spdlog-build/spdlog.build/Release/ALL_BUILD.build/Script-C239D05C9752437B977BDA30.sh
    cd /tmp/spdlog
    /bin/sh -c /tmp/spdlog-build/spdlog.build/Release/ALL_BUILD.build/Script-C239D05C9752437B977BDA30.sh
echo ""

echo Build\ all\ projects
Build all projects

=== BUILD AGGREGATE TARGET install OF PROJECT spdlog WITH CONFIGURATION Release ===

Check dependencies

Write auxiliary files
write-file /tmp/spdlog-build/spdlog.build/Release/install.build/Script-D6999603A1034FE0802CA994.sh
chmod 0755 /tmp/spdlog-build/spdlog.build/Release/install.build/Script-D6999603A1034FE0802CA994.sh

PhaseScriptExecution CMake\ PostBuild\ Rules /tmp/spdlog-build/spdlog.build/Release/install.build/Script-D6999603A1034FE0802CA994.sh
    cd /tmp/spdlog
    /bin/sh -c /tmp/spdlog-build/spdlog.build/Release/install.build/Script-D6999603A1034FE0802CA994.sh
/Applications/CMake.app/Contents/bin/cmake -DBUILD_TYPE=Release -P cmake_install.cmake
-- Install configuration: "Release"
-- Installing: /tmp/3rd/include/spdlog
-- Installing: /tmp/3rd/include/spdlog/async_logger.h
-- Installing: /tmp/3rd/include/spdlog/common.h
-- Installing: /tmp/3rd/include/spdlog/details
-- Installing: /tmp/3rd/include/spdlog/details/async_log_helper.h
-- Installing: /tmp/3rd/include/spdlog/details/async_logger_impl.h
-- Installing: /tmp/3rd/include/spdlog/details/file_helper.h
-- Installing: /tmp/3rd/include/spdlog/details/log_msg.h
-- Installing: /tmp/3rd/include/spdlog/details/logger_impl.h
-- Installing: /tmp/3rd/include/spdlog/details/mpmc_bounded_q.h
-- Installing: /tmp/3rd/include/spdlog/details/null_mutex.h
-- Installing: /tmp/3rd/include/spdlog/details/os.h
-- Installing: /tmp/3rd/include/spdlog/details/pattern_formatter_impl.h
-- Installing: /tmp/3rd/include/spdlog/details/registry.h
-- Installing: /tmp/3rd/include/spdlog/details/spdlog_impl.h
-- Installing: /tmp/3rd/include/spdlog/fmt
-- Installing: /tmp/3rd/include/spdlog/fmt/bundled
-- Installing: /tmp/3rd/include/spdlog/fmt/bundled/format.cc
-- Installing: /tmp/3rd/include/spdlog/fmt/bundled/format.h
-- Installing: /tmp/3rd/include/spdlog/fmt/bundled/ostream.cc
-- Installing: /tmp/3rd/include/spdlog/fmt/bundled/ostream.h
-- Installing: /tmp/3rd/include/spdlog/fmt/bundled/posix.cc
-- Installing: /tmp/3rd/include/spdlog/fmt/bundled/posix.h
-- Installing: /tmp/3rd/include/spdlog/fmt/bundled/time.h
-- Installing: /tmp/3rd/include/spdlog/fmt/fmt.h
-- Installing: /tmp/3rd/include/spdlog/fmt/ostr.h
-- Installing: /tmp/3rd/include/spdlog/formatter.h
-- Installing: /tmp/3rd/include/spdlog/logger.h
-- Installing: /tmp/3rd/include/spdlog/sinks
-- Installing: /tmp/3rd/include/spdlog/sinks/android_sink.h
-- Installing: /tmp/3rd/include/spdlog/sinks/ansicolor_sink.h
-- Installing: /tmp/3rd/include/spdlog/sinks/base_sink.h
-- Installing: /tmp/3rd/include/spdlog/sinks/dist_sink.h
-- Installing: /tmp/3rd/include/spdlog/sinks/file_sinks.h
-- Installing: /tmp/3rd/include/spdlog/sinks/msvc_sink.h
-- Installing: /tmp/3rd/include/spdlog/sinks/null_sink.h
-- Installing: /tmp/3rd/include/spdlog/sinks/ostream_sink.h
-- Installing: /tmp/3rd/include/spdlog/sinks/sink.h
-- Installing: /tmp/3rd/include/spdlog/sinks/stdout_sinks.h
-- Installing: /tmp/3rd/include/spdlog/sinks/syslog_sink.h
-- Installing: /tmp/3rd/include/spdlog/sinks/wincolor_sink.h
-- Installing: /tmp/3rd/include/spdlog/spdlog.h
-- Installing: /tmp/3rd/include/spdlog/tweakme.h
-- Installing: /tmp/3rd/lib/cmake/spdlog/spdlogConfig.cmake
-- Installing: /tmp/3rd/lib/cmake/spdlog/spdlogConfigVersion.cmake
-- Installing: /tmp/3rd/lib/pkgconfig/spdlog.pc
-- Installing: /tmp/3rd/lib/cmake/spdlog/spdlogTargets.cmake

** BUILD SUCCEEDED **

Notice the installed .cmake files and spdlog.pc

  • .cmake - Facilitates to use this package from other CMake projects
  • spdlog.pc - Facilitates to use this package from other projects using the pkg-config utility

Introduce spdlog in TickCounter project

Use a new branch and name it "logger".


In [16]:
%%bash
cd /tmp/TickProject

git checkout -b logging

# git branch logging
# git checkout logging


Switched to a new branch 'logging'

Add some code using spdlog and fix build system


In [17]:
%%bash
. quickci Log4 Log5 Log6
git log


[logging 38deed5] Fixed Log4
 2 files changed, 18 insertions(+), 11 deletions(-)
[logging 263f816] Fixed Log5
 2 files changed, 11 insertions(+), 5 deletions(-)
[logging ea49c43] Fixed Log6
 2 files changed, 8 insertions(+), 12 deletions(-)
commit ea49c4358bc28ce84d05a08b41eecb1d6109f74d
Author: Tommy Carlsson <topcatse@yahoo.se>
Date:   Sun Apr 30 19:35:06 2017 +0200

    Fixed Log6

commit 263f8162e3e9c1a0b16c5ea5e49a1831285f2294
Author: Tommy Carlsson <topcatse@yahoo.se>
Date:   Sun Apr 30 19:35:06 2017 +0200

    Fixed Log5

commit 38deed56b7f659ebc306c0d877e8570e41fdf198
Author: Tommy Carlsson <topcatse@yahoo.se>
Date:   Sun Apr 30 19:35:06 2017 +0200

    Fixed Log4

commit 6845752eb01a38258ee752c90c6caf18813a33e6
Author: Tommy Carlsson <topcatse@yahoo.se>
Date:   Sun Apr 30 19:30:24 2017 +0200

    Initial revision

commit 19b738a045a3b7ceefe31ffcfe93020437b64a18
Author: Tommy Carlsson <topcatse@yahoo.se>
Date:   Sun Apr 30 19:28:41 2017 +0200

    Initial revision

Check differences in SourceTree. Build and run.


In [18]:
%%bash
cd /tmp/TickProject
ninja -C build


ninja: Entering directory `build'
[0/1] Regenerating build files
The Meson build system
Version: 0.39.1
Source dir: /private/tmp/TickProject/src
Build dir: /private/tmp/TickProject/build
Build type: native build
Project name: TickCounterProject
Native cpp compiler: c++ (clang 8.1.0)
Build machine cpu family: x86_64
Build machine cpu: x86_64
Found pkg-config: /usr/local/bin/pkg-config (0.29.2)
Native dependency spdlog found: YES 1.0.0
Dependency threads found: YES
Build targets in project: 1
[1/2] Compiling cpp object 'tickcounter@exe/main.cpp.o'
[2/2] Linking target tickcounter
clang: warning: argument unused during compilation: '-pthread' [-Wunused-command-line-argument]

Merge logging branch into master

There are different conceps involved in a merge or could be.

  • Fast forward
  • Three-way merge
  • Rebase
  • Conflicts

Fast forward

Three-way merge


Rebase (change the history)



Merge conflict

Let's create a conflict on the last line in main.cpp

Also perform development on a another branch. Let's call it features.


In [19]:
%%bash
cd /tmp/TickProject/src
git checkout master
git branch features


Switched to branch 'master'

In [20]:
%%bash
cd /tmp/TickProject/src
echo This row at the end will prevent TickProject from building >> main.cpp
git diff
git commit -am "This will be a conflict"


diff --git a/src/main.cpp b/src/main.cpp
index 1dfe1bc..a0c98f7 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -40,3 +40,4 @@ int main(int argc, char* argv[])
   
   return 0;
 }
+This row at the end will prevent TickProject from building
[master 12b6581] This will be a conflict
 1 file changed, 1 insertion(+)

Add some features on the features branch


In [21]:
%%bash
cd /tmp/TickProject/src
git checkout features
sed -i 's/Hello World/Hello Makers/g' main.cpp
git diff
git commit -am "Changed greeting"


diff --git a/src/main.cpp b/src/main.cpp
index 1dfe1bc..360c171 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -24,7 +24,7 @@ private:
 
 int main(int argc, char* argv[])
 {
-  cout << "Hello World!" << endl;
+  cout << "Hello Makers!" << endl;
   
   TickReceiver receiver;
 
[features b5ea177] Changed greeting
 1 file changed, 1 insertion(+), 1 deletion(-)
Switched to branch 'features'

In [22]:
%%bash
cd /tmp/TickProject/src
echo // This row at the end will compile >> main.cpp
git diff
git commit -am "Added a row at the end of main.cpp"


diff --git a/src/main.cpp b/src/main.cpp
index 360c171..cf104bc 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -40,3 +40,4 @@ int main(int argc, char* argv[])
   
   return 0;
 }
+// This row at the end will compile
[features fbc1457] Added a row at the end of main.cpp
 1 file changed, 1 insertion(+)

Merge features onto master --> Conflict

Check always out the branch which shall be modified!


In [26]:
%%bash
cd /tmp/TickProject/src
git checkout master
git merge features


Auto-merging src/main.cpp
CONFLICT (content): Merge conflict in src/main.cpp
Automatic merge failed; fix conflicts and then commit the result.
Already on 'master'

Resolve conlict in SourceTree

Commit merge


In [27]:
%%bash
cd /tmp/TickProject/src
git status


On branch master
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:

	modified:   main.cpp


In [28]:
%%bash
cd /tmp/TickProject/src
git commit -am "Features added"


[master 1fe644d] Features added

Rebase

This rebase scenario will target these goals:

  • The logging branch (spdlog) is merged into the master branch
  • An appropriate commit message (i.e, not 'Fixed Log6')
  • Only one commit from logging (squash several commits to one)

In [29]:
%%bash
cd /tmp/TickProject
git checkout logging


Switched to branch 'logging'

I usually create a tmp branch at this point (If something goes wrong, just remove after)


In [30]:
%%bash
cd /tmp/TickProject
git branch logging-tmp

Use git rebase interactively to squash the logging branch

Use git rebase interactively Let's perform this in SourceTree via a terminal.

Like so: git rebase -i 06558f1d77a09bb41a97bf3eda20e1af3f551a39

After squash


In [31]:
%%bash
cd /tmp/TickProject
git checkout logging
git rebase master


First, rewinding head to replay your work on top of it...
Applying: Introduced spdlog
Using index info to reconstruct a base tree...
M	src/main.cpp
Falling back to patching base and 3-way merge...
Auto-merging src/main.cpp
CONFLICT (content): Merge conflict in src/main.cpp
Patch failed at 0001 Introduced spdlog
The copy of the patch that failed is found in: .git/rebase-apply/patch

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".

Already on 'logging'
.git/rebase-apply/patch:32: trailing whitespace.
    
.git/rebase-apply/patch:34: trailing whitespace.
    
.git/rebase-apply/patch:53: trailing whitespace.
    
.git/rebase-apply/patch:65: trailing whitespace.
spdlog_inc = include_directories(spdlog_dep.get_pkgconfig_variable('includedir')) 
warning: 4 lines add whitespace errors.
error: Failed to merge in the changes.

After rebase of logging

Now master can be updated with a fast forward merge of logging


In [32]:
%%bash
cd /tmp/TickProject
git checkout master
git merge logging


Updating 1fe644d..1ec464f
Fast-forward
 src/main.cpp    | 27 ++++++++++++++++-----------
 src/meson.build |  6 +++++-
 2 files changed, 21 insertions(+), 12 deletions(-)
Switched to branch 'master'

Remove logging-tmp


In [33]:
%%bash
cd /tmp/TickProject
git branch -d logging-tmp


error: The branch 'logging-tmp' is not fully merged.
If you are sure you want to delete it, run 'git branch -D logging-tmp'.

In [34]:
%%bash
cd /tmp/TickProject
git branch -D logging-tmp


Deleted branch logging-tmp (was ea49c43).

Reflog to your help if something has gone really wrong


In [35]:
%%bash
cd /tmp/TickProject
git reflog


1ec464f HEAD@{0}: merge logging: Fast-forward
1fe644d HEAD@{1}: checkout: moving from logging to master
1ec464f HEAD@{2}: rebase finished: returning to refs/heads/logging
1ec464f HEAD@{3}: commit: Added logging
1fe644d HEAD@{4}: rebase: checkout master
a605e52 HEAD@{5}: checkout: moving from logging to logging
a605e52 HEAD@{6}: rebase -i (finish): returning to refs/heads/logging
a605e52 HEAD@{7}: rebase -i (fixup): Introduced spdlog
ae1feae HEAD@{8}: rebase -i (fixup): # This is a combination of 2 commits.
4c4c9bf HEAD@{9}: rebase -i (reword): Introduced spdlog
38deed5 HEAD@{10}: cherry-pick: fast-forward
6845752 HEAD@{11}: rebase -i (start): checkout 6845752eb01a38258ee752c90c6caf18813a33e6
ea49c43 HEAD@{12}: checkout: moving from master to logging
1fe644d HEAD@{13}: commit (merge): Features added
7596e60 HEAD@{14}: checkout: moving from master to master
7596e60 HEAD@{15}: commit: Added gitignore
12b6581 HEAD@{16}: reset: moving to 12b6581c08cf794e6152e5b11428fdb644515822
69c6fcb HEAD@{17}: commit: Merge branch 'features'
fc0826a HEAD@{18}: commit (merge): Added gitignore
12b6581 HEAD@{19}: checkout: moving from features to master
fbc1457 HEAD@{20}: commit: Added a row at the end of main.cpp
b5ea177 HEAD@{21}: commit: Changed greeting
6845752 HEAD@{22}: checkout: moving from master to features
12b6581 HEAD@{23}: commit: This will be a conflict
6845752 HEAD@{24}: checkout: moving from logging to master
ea49c43 HEAD@{25}: commit: Fixed Log6
263f816 HEAD@{26}: commit: Fixed Log5
38deed5 HEAD@{27}: commit: Fixed Log4
6845752 HEAD@{28}: checkout: moving from master to logging
6845752 HEAD@{29}: commit: Initial revision
19b738a HEAD@{30}: commit (initial): Initial revision

Some more Git concepts

  • Detached HEAD - HEAD pointes to a commit (not a good state to be in)
  • Hunk - stage and/or discard changes of a file
  • Amend - fix last commit code and/or message
  • Stash - put changes in the stash
  • Blame - check who did what in a file
  • Cherry pick - get files from a commit

In [36]:
!. quickedit v0.2

GitHub

  1. Create a repository on your GitHub account @ https://github.com
  2. Bind your local account to the GitHub upstream repository
  3. Clone upstream repository to a second repository
  4. Add some code on a new branch travis and push upstream
  5. On secondary repository, fetch from upstream and merge or do a pull
  6. Create a pull request

2. Bind


In [40]:
%%bash
cd /tmp/TickProject
git checkout master
git remote add origin https://github.com/topcatse/TickProject.git
git push --set-upstream origin master


M	src/main.cpp
M	src/meson.build
Branch master set up to track remote branch master from origin.
Already on 'master'
Everything up-to-date

3. Clone TickProject from GitHub to a second repository


In [41]:
%%bash
cd /tmp
git clone https://github.com/topcatse/TickProject.git TickProject2
cd TickProject2
tree -aCI .git


.
├── .gitignore
└── src
    ├── KeyTicker.h
    ├── TickerInterface.h
    ├── main.cpp
    └── meson.build

1 directory, 5 files
Cloning into 'TickProject2'...

In [42]:
%%bash
cd /tmp
ls -l


total 5976
drwxr-xr-x   4 tommy         wheel      136 Apr 30 19:34 3rd
drwxr-xr-x   6 tommy         wheel      204 May  1 22:56 TickProject
drwxr-xr-x   5 tommy         wheel      170 May  1 23:01 TickProject2
drwx------   3 tommy         wheel      102 Apr 24 20:58 com.apple.launchd.7DNtr1FyaN
drwx------   3 _mbsetupuser  wheel      102 Apr 24 20:58 com.apple.launchd.NxV3I8W45z
drwx------   3 _mbsetupuser  wheel      102 Apr 24 20:58 com.apple.launchd.YA0N0Q6VN1
drwx------   3 tommy         wheel      102 Apr 24 20:58 com.apple.launchd.nrF2Bt7BQG
drwx------   5 tommy         wheel      170 Apr 24 21:04 ctr-271470687
drwx------   5 tommy         wheel      170 Apr 24 21:04 ctr-853333316
drwxr-xr-x  15 tommy         wheel      510 Apr 30 19:33 spdlog
drwxr-xr-x@ 12 tommy         wheel      408 Apr 30 19:34 spdlog-build
-rw-r--r--   1 root          wheel  2019478 Apr 25 16:50 wifi-04-25-2017__16:50:03.log
-rw-r--r--   1 root          wheel  2048000 Apr 29 15:49 wifi-04-29-2017__15:49:54.log
-rw-r--r--   1 root          wheel  2048000 Apr 29 18:56 wifi-04-29-2017__18:56:04.log

4. Add some code locally in a new branch 'travis' and push upstream


In [43]:
%%bash
cd /tmp/TickProject
git checkout -b travis
git archive --format=tar --remote=~/src/maker-presentation v0.2 .travis.yml | tar xf -
git add .travis.yml
git commit -am "Added travis-ci build"
git push -u origin travis


M	src/main.cpp
M	src/meson.build
[travis ebf44f0] Added travis-ci build
 3 files changed, 57 insertions(+), 22 deletions(-)
 create mode 100644 .travis.yml
Branch travis set up to track remote branch travis from origin.
Switched to a new branch 'travis'
To https://github.com/topcatse/TickProject.git
 * [new branch]      travis -> travis

5. Fetch from upstream to TickProject2


In [44]:
%%bash
cd /tmp/TickProject2
git fetch origin
git branch -a


* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
  remotes/origin/travis
From https://github.com/topcatse/TickProject
 * [new branch]      travis     -> origin/travis

In [45]:
%%bash
cd /tmp/TickProject2
# git checkout -b travis --track origin/travis
git checkout travis


Branch travis set up to track remote branch travis from origin.
Switched to a new branch 'travis'

6. At GitHub create a pull request to merge travis into master. Acknowledge. Update TickCounter2!


In [46]:
%%bash
cd /tmp/TickProject2
git fetch origin
git branch -a


  master
* travis
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
  remotes/origin/travis
From https://github.com/topcatse/TickProject
   1ec464f..47ca2d3  master     -> origin/master

In [47]:
%%bash
cd /tmp/TickProject2
git checkout master
git log master..origin/master


Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)
commit 47ca2d3d7edd2db19fe0e0e4f279e211c17ceb9c
Merge: 1ec464f ebf44f0
Author: Tommy Carlsson <topcatse@yahoo.se>
Date:   Mon May 1 23:03:06 2017 +0200

    Merge pull request #1 from topcatse/travis
    
    Added travis-ci build

commit ebf44f0da3b41cb5c7458af2f7530ff4f93e7b5a
Author: Tommy Carlsson <topcatse@yahoo.se>
Date:   Mon May 1 23:01:47 2017 +0200

    Added travis-ci build
Switched to branch 'master'

In [48]:
%%bash
cd /tmp/TickProject2
git merge origin/master
git status


Updating 1ec464f..47ca2d3
Fast-forward
 .travis.yml     | 45 +++++++++++++++++++++++++++++++++++++++++++++
 src/main.cpp    | 28 +++++++++++-----------------
 src/meson.build |  6 +-----
 3 files changed, 57 insertions(+), 22 deletions(-)
 create mode 100644 .travis.yml
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean

Continuous integration

  • Jenkins
  • TeamCity
  • GitLab
  • Bamboo
  • Travis-CI