Working Together @MiPih as ToolSmiths |
#jenkins #java #maven #nexus #sonarqube #build #docker #passion
This is a workshop. So there will be manipulation, don’t worry !
Basic concepts & commands reminder
Repository lifecycle
Git workflows discussion
For the first 10 years of kernel maintenance, we literally used tarballs and patches, which is a much superior source control management system than CVS is – Linus TorvaldsLinus Torvalds
Closed-source DVCS. Free licenses provided to the project.
⇒ Revocation triggered by Andrew Tridgell’s BitKeeper protocol reverse-engineering
I’m an egotistical bastard, and I name all my projects after myself. First Linux, now git.Linus Torvalds
Whole project history present locally
If it takes half a minute to apply a patch […] then a series of 250 emails […] takes two hours.
adds to the index (-p lets you choose the parts of your file you actually want to add)
staging area (a sweet place to lovingly craft your commits)
Captures the state of the index.
echo "dingdingdingbabababaaaaa" >> theFile # (1)
git add theFile
echo "blah" > theFile # (2)
git commit -m "done"
Right answer: (1) |
|
(note: difference with svn ⇒ (2)) |
File content, identified by a hash
List of pointers to blob, or tree, identified by a hash
References the (root) tree + metadata, 0 to n parent commits, identified by a hash
Identified by a SHA-1 hash :
|
Possibly: Author ≠ Committer |
DAG : Directed Acyclic Graph |
Name associated with a commit (+ potential metadata)
Quiz: what does this?
$ git init pouet && cd pouet
$ git commit -m "initial commit" --allow-empty
$ echo abc > .git/refs/heads/paf
Creates a branch! That’s right!
$ git init pouet && cd pouet
$ git commit -m "initial commit" --allow-empty
$ echo abc > .git/refs/heads/paf
$ git branch
* master
paf
So… What are branches again?
Unreferenced commits will be garbaged eventually
HEAD
: shorthand to the latest commit of the current branch
HEAD~N
: N commit before the last one
master
(or any branch): automatically bumped when new commit is done on itgit reset [--soft|--mixed|--hard] <TARGET>
|
Example:
git reset HEAD~
Example:
git reset --hard HEAD~2
What is it? How to choose one or another?
What do you want to do?
Git lets you express what you did.
Correction
Git lets you express what you wanted to do.
Here’s what it’s all about:
Good SCM history reveals intentions.
Like good code.
What you want to express :
when you don’t want your local history to be seen as side/sub-work
it was side/sub-work
(on feature) git rebase master
Rewinding:
Rewinding:
Replaying:
Replayed:
Rebased:
(on master) git merge feature
After (merge commit
created):
fast-forward
: bumping the branch pointergit merge --no-ff
optionUsing Merge |
Using Rebase |
|
|
Git reflog can save your a$$: keeps track of everywhere you went by
Example:
$ git reflog
f7d3b1 HEAD@{0}: commit (amend): Added reset + compulsory lolcat
440a3bf HEAD@{1}: commit (amend): Added reset + details
c830885 HEAD@{2}: commit: Ajout reset
36b4dce HEAD@{3}: commit: Passe sur les ajustements: ff, intro...
5ef0aa8 HEAD@{4}: commit (amend): On sa mis dacor
8e51635 HEAD@{5}: rebase -i (finish): returning to refs/heads/master
8e51635 HEAD@{6}: rebase -i (fixup): On s'a mis dacor
b6d8c99 HEAD@{7}: rebase -i (pick): On s'a mis dacor
What if you know you introduced a bug between one commit and another?
But there’s 1000 commits between them?
How to find out the offending one?
Granularity
One repository, one lifecycle.
How to aggregate many repositories afterwards? Just merge!
git init repo1 && cd repo1 && git commit -m "Initial 1" --allow-empty && cd ..
git init repo2 && cd repo2 && git commit -m "Initial 2" --allow-empty
git remote add other file://$PWD/../repo1
git fetch other
git merge other/master -m "let's merge them"
git log --oneline --graph
* c2be901 let's merge them
|\
| * 1763514 Initial 1
* 8208b0a Initial 2
How to explode one repository into multiple ones, remove some file from all commits…
filter-branch is your friend.
EGit has been pretty buggy in the past, but now has become definitely usable.
Even supports some of the features where GUI actually makes a lot of sense: staging interactively the lines you want.
JGit provides (among others) a fluent API to interact with Git repositories:
Git.cloneRepository()
.setDirectory("/path/to/git/repository")
.setURI("git://gitserver/somerepo.git")
.setBare(false)
.call();
Git.open("/some/repository")
.fetch()
.setRemoveDeletedRefs(true)
.setTagOpt(TagOpt.FETCH_TAGS)
.call();
Tell me and I forget, teach me and I may remember, involve me and I learn.Benjamin Franklin
/