Git : Working collaboratively

Marie-Pierre Etienne

https://github.com/MarieEtienne/reproductibilite

2025-09-10

Brief Reminder of Basic Git

Commit tree

simple branche

Write the commit tree of MarieEtienne/stats-reminder repo with the actual commit number

git clone .... ## cloning the repo
git ...  ## print history

Remark: To show only the last 3 commits you can use

git log -n 3

A first commit

  • Open the file Penguins_chapter.qmd and add your name and the list of authors, then save your file.
git status # project status
git diff
  • Type the command git add Penguins_chapter.qmd, then repeat the previous commands.

  • Type the command git commit -m "Change title", and once again check the project status.

  • Draw the commit tree.

simple branche

Process overview

bilan1

The snapshot analogy

  • In the working directory, let’s try different poses (the version of the project in the working directory)

  • When satisfied by the pose of one guy, ask him stop moving (Staging area)

  • When satisfied with the whole scene, take the photo (Commit in the local repo)

Share your progress with your co workers

The current version of the project is indeed recorded in the version control system, but you are the only ones who know it.

You may want to share these changes to the remote repository from which we started.

  • To view the differences with the remote repository, use git diff origin/master.

  • To send our changes, , use git push.

bilan1

bilan1

bilan1

  • Most of view receive errors message like
To github.com:MarieEtienne/stats-reminders.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'github.com:MarieEtienne/stats-reminders.git'
hint: Updates were rejected because the remote contains work that you do not
hint: have locally. This is usually caused by another repository pushing to
hint: the same ref. If you want to integrate the remote changes, use
hint: 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

, why ?

  • Draw the commit tree.

Share your progress with your co workers

bilan1

  • Be sure that all your changes have been committed

  • when works are diverged, you can have different attitudes. We go for the simple one for now and we need to specify this config for git

git config pull.rebase false
  • Retrieve the last version of the project on the server: git pull origin master

  • This might highlights conflicts: In case of conflict, you receive a very nasty message.

Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.
  • Share the merged version on the server
  • Solving conflicts implies choosing and You must resolve the conflict
<<<<<<< HEAD
It will also served as sandbox during the lectures. Therefore the git history might be a bit fuzy.

=======
It will be used as sandbox during the lectures. Don't be scared by the messy git tree!
>>>>>>> dfdf5995ade6e47899531a99e5947e719da86020

Portion between <<<<<<< HEAD and ======= is your local version, while part between =======and >>>>>>> dfdf5995ade6e47899531a99e5947e719da86020 is the version available at commit with hash dfdf5995ade6e47899531a99e5947e719da86020.

git pull origin master # retrieve the laste version on the server and try to merge with yours
git status # see the conflicted files
## revise each conflicted file to remove conflicts
git add any files with solved conflicts
git commit -m "Merge conflicts solved"
git push

Problem: the merge commit is not very readable in the development process. But one step at a time

  • Change someting in your local version of Penguins_chapter.qmd,

  • git add, commit, pull …..

  • Solve conflicts

  • `git push’

Problem: Too much time spent at solving conflicts. We need another to minimize conflilcts

bilan1

T1 bilan1

T2 bilan1

T3 bilan1

Associate trees with actions

One branch for one task

Goal minimising conflicts

Working in parralel and merging from time to time

Working in parallel:

bilan1

Merging test within master: bilan1

Creat a local branch and navigating between different branches

git branch mpe_test_branch # create a branch
git branch -a # list the branch and indicates on which you are sitting
git switch  mpe_test_branch # switch/jump on mpe_test_branch
git branch -a 
git switch master
git branch -d mpe_test_branch # deletes the branch
  • Create your own branch and make some changes, add and commit them and now trying to push
git push origin YOUR_BRANCH_NAME
git switch master #go back on the master branch
git branch -a #list all the branchs and show on which you are sitting

Go on Github and look !

  • Create a second test branch test_branch2 and make some changes

  • We want to incorprate change make in test_branch2 in your personnal branch

git switch YOUR_BRANCH_NAME
git merge test_branch2 #merging the commits of test_branch2 in the branch you are sitting
## look at your files
  • Creates your own test_branch from the master branch and go on this branch

  • Remove Penguins_chapter.qmd from the versioning system git rm Penguins_chapter.qmd

  • list the content your directory

  • Commit your changes in your branch

  • Switch to the master branch

  • List the contents of your directory

  • Delete your test_branch git branch -d NAME_OF_YOUR_BRANCH

  • Create a branch and switch to this branch

  • Create a qmd file, name `Row_id.qmd”, id being the order of your row, 1 is the closes to the board.

  • Work by team, (a team = a row), to crate and solve conflicts

Writing a clean history - a proper way to merge

Retrieve latest history

git fetch origin
  • Updates your local references to remote branches

  • Does not change your working directory

  • Prepares you to rebase onto the latest master

Before fetch

A A B B A->B C C B->C F F C->F G G F->G HEAD HEAD HEAD->G mybranch mybranch mybranch->G master master master->C

After fetch

A A B B A->B C C B->C D D C->D F F C->F E E D->E G G F->G HEAD HEAD HEAD->G mybranch mybranch mybranch->G master master master->C origin_master origin/master origin_master->E

Suppose you are on your feature branch:

git rebase origin/master 

Re-applies your commits on top of the latest master Lets you resolve conflicts now, instead of later during merge

Before rebase

A A B B A->B C C B->C D D C->D F F C->F E E D->E G G F->G HEAD HEAD HEAD->G mybranch mybranch mybranch->G master master master->C origin_master origin/master origin_master->E

After rebase

A A B B A->B C C B->C D D C->D E E D->E F F E->F G G F->G HEAD HEAD HEAD->G mybranch mybranch mybranch->G master master master->C origin_master origin/master origin_master->E

Once rebase was successful:

git switch master
git merge mybranch

Since history is linear, this is a fast-forward merge

No extra merge commits

History stays clean and easy to read

After switch, before merge

A A B B A->B C C B->C D D C->D E E D->E F F E->F G G F->G HEAD HEAD HEAD->C mybranch mybranch mybranch->G master master master->C origin_master origin/master origin_master->E

After merge

A A B B A->B C C B->C D D C->D E E D->E F F E->F G G F->G HEAD HEAD HEAD->G mybranch mybranch mybranch->G master master master->G origin_master origin/master origin_master->E

  • git fetch: update local info about remote

  • git rebase origin/master: reapply work on top of your branch

  • git merge: integrate cleanly

  • you can delete your branch once your work is included

Going back in time : restore version – checkout

To go back to a previous specific version, use the checkout command

git log --oneline
git checkout C # c = specific hash number

The current working version of Penguins_chapter.qmd is in the state of commit A_specific_hash_version_number

A A B B A->B C C B->C D D C->D E E D->E F F E->F HEAD HEAD HEAD->C master master master->F

You can branch from this moment if you want to and start developping this new branch

git switch -c the_new_branch # create and switch to the branch
git commit ....

The current working version of Penguins_chapter.qmd is in the state of commit A_specific_hash_version_number

A A B B A->B C C B->C D D C->D G G C->G E E D->E F F E->F H H G->H new_b the_new_branch new_b->H HEAD HEAD HEAD->H master master master->F

Go back to the latest version on master by

git switch master

Everything is back to normal!

A A B B A->B C C B->C D D C->D G G C->G E E D->E F F E->F H H G->H HEAD HEAD HEAD->F new_b the_new_branch new_b->H master master master->F

Removing a local commit (not present on the remote repo)

The purpose of reset function

To remove all history, going back in commit number G (remove definitely commit H and I)

git log --oneline
git reset --hard G
git log --oneline

Be very very very careful, it is a destructive process. All information regarding your previous commit is lost.

Before reset

A A B B A->B C C B->C D D C->D G G C->G E E D->E F F E->F H H G->H I I H->I HEAD HEAD HEAD->I new_b local_branch new_b->I master master master->F

After reset

A A B B A->B C C B->C D D C->D G G C->G E E D->E F F E->F HEAD HEAD HEAD->G new_b local_branch new_b->G master master master->F

It’s a very dangerous way of living with Git, an unfortunate removal of a commit present on the remote server can break the commit trees for all your coworkers and you won’t have friends anymore.

  • Remove the file Penguins_chapter.qmd, and commit this change

  • List the contents of your directory

  • Go back one commit in time using reset

  • List the contents of your directory

How to suppress a commit shared on the remote repo

You can’t destroy common history, you have to update it

You can “suppress” this commit by applying the opposit! Let’s we want to remove change in the project made in commit \(B\)

git log --oneline
git revert B
git log --oneline

Only th change made to come from A to B are reversed. Of course it might produce conflicts you have to solve.

This becomes more difficult with dirty merge commits, so try to keep a clean history

Before reset

A A B B A->B C C B->C D D C->D HEAD HEAD HEAD->D master master master->D

After revert

A A B B A->B C C B->C D D C->D E -B D->E HEAD HEAD HEAD->E master master master->E

Conclusion

Last few words

  • Git is a standard control version system in industry AND research for version control (whether you use it with Github or not),

  • Being proficient with Git requires to use it as much as possible: The more problems you have, the more you learn

  • Go back to the documentation as much as needed

  • By no means, Git is an alternative to a proper documented code (in R you might want to use package like formatR, styleR and document it with roxygen)

Evaluation

  • A short quizz on November 5th, to check your understanding of git behaviours command, errors and message. It could be explaining in words the development of a project by looking at a project history, explaining the actions to be taken according to one mean git message, explaining the purpose of one command. No need to learn commands, regulard practice before this date should be enough.

  • Stats reminder project

    • I will be looking at the qality of the commits
    • The use of PR
    • Respect the checks
    • Review Other’s work
  • For next session: 3 teams

    • the linear model team
    • the factorial analysis team
    • The Differential equation team

    Within each team, 3 specific mthods within the gen,eral team, illusrated by an ecological example.

Some help other than Claude.ai and ChatGPT

Resources

Cheat sheet

Git Cheat sheet

To be used as a Sandbox

Learning Git Demo