Skip to content

Git and Github

Marc edited this page Mar 6, 2024 · 15 revisions

Branch structure

The branch structure of our project follows a simple structure:

  • the main contains only the versions for the official releases
    • All commits in main are tagged with the version of the release
    • hotfix branches may be created from the commits of main in the rare case that old major versions need maintainance
  • the dev branch is the contains the most up to date version of the sources
  • many short lived feature/fix branches that branch (merge) from (to) dev

The following schema shows the idea of the structure

         
 unmerged-fix               *--*--* (work in progress)
                           /  
 merged-feat     *--*--*  /
                /       \/
 dev           *---------*
                \ v10.1   \ v10.2
 main          --*---------*
                  \
v10.1-hotfix       *

Typical workflow on Github

Note that this is a typical workflow, some steps may vary, skipped or done in another way

  • Create an issue describing the feature, bug of refactoring to be worked on
  • In the issue page in the right information bar, on the Development section click Create branch
    • The new branch will branch from dev as it is the default one
  • Fetch the branch (git fetch) from Github to your local copy of the repo
    • Github proposes you how to do it in the previous step
  • Switch to your branch (git switch branch-name), code and commit changes
  • Upon finishing, push your commits to Github (git push on your branch)
  • In Github create a pull request for your branch and request the review of at least one other member of the team
  • Discuss possible changes and fixes, make new commits if necessary and push them
    • The discuss/fix/push cycle may be repeated many times
    • The discussion cycle must be short and effective, and focus on resolving the issue
    • Create new issues if necessary for related problems
  • Once the discussion is resolved the reviewer approves the PR and you merge the changes into dev

Variations

  • The branch may be created beforehand and then associated to an issue
  • Many issues may be closed with one MR
    • This is to encourage opportunistic fixes

Commit Guidelines

Commits should be as atomic as possible, while being not too small to be linked to a consistent minimal update

Useful alias

The following git alias shows the commit log as a DAG in choronolical order

# Configure once
git config --global alias.lol log --graph --decorate --pretty=oneline --abbrev-commit --all --author-date-order

# To execute the alias
git lol

Minimum guide to getting started with main git commands

New local repo

git clone https://github.com/KhiopsML/khiops.git

pre-commit install

  • Pre-commit allow to standardise the files: formatting, adding licences, etc.
  • They are performed automaticaly before each commit.
  • You can also force a pre-commit: pre-commit run --all-files

Branches

git branch --all: to see all branches on your local repo

git switch branch_name: to switch to your branch

Prepare a commit

git status gives you usefull info: current branch, and current status of modified files

To manage the files to be added to the commit

  • git add -u: to take into account all updates files
  • git add file_name: to add a specific file
  • git mv file_name new_file_name: to rename a file

Make a commit

Standard commit

  • git commit
    • note that if the pre-commit has modified certain files, you must add them again before a new commit
  • git push: to update to central repo

Update previous commit for a minor change (ex: typo)

  • git commit --amend
  • git commit --amend --no-edit: idem, without updating the commit message
  • git push --force: to force the update of the central repo by replacing the commit by the update

Commit message

  • first line should short
  • followed by an empty line, and then detailed comments if necessary
  • good practise
    • use your IDE to check your changes and write a synthetic summary

Rebase a branch

You may want to refresh a branch if its origin has been updated since the branch was developed.

You thus need to rebase your branch branch-name on dev

  • refresh the local repo on dev git switch dev git fetch git pull
  • take into account the last commit of dev git switch branch-name git rebase dev
  • resolve conflicts and rebuild a commit

Pull request

Prerequistes:

  • first, rebase your branch branch on dev to get the last version of the source
  • tests on the standard family will be carried out automatically using CICD
  • for major pull requests, may require all LearningTest non-regression tests to be verified

History of commit notes

  • complete: git log
  • complete, with titles only: git log --oneline
  • last n commits: git log -(n)
  • show log in UI mode: gitk

See previous versions of a file

git log -p file_name: show last updates in shell mode

gitk file_name: in UI mode

Using github for temporary backups

Need: periodically save the current branch, even if it has not reached a stable state

  • make temporary commits, with the commit message prefixed with WIP (work in progress)
    • make pushes to save them on the central repo
  • once development has stabilised, merge these temporary commits into a single commit (squash) cf. https:\www.ekino.fr\publications\how-to-squash-efficiently-its-commits-with-git\
    • First of all, you need to get the sha1 (commit_hash) of the commit preceding the one you are going to squash
      • using git log --oneline
    • then use it to run the command: git rebase -i commit_hash
    • You then enter interactive mode (using the git editor).
      • Commits are displayed from the oldest to the most recent.
      • The first commit is the basic one, the one you want to keep; so leave the "pick" instruction in front of it.
      • We want to squash all subsequent commits, so we put the "squash" instruction in front of them.
    • In concrete terms, we tell GIT to base itself on the first commit and we apply all the subsequent commits to make just one.
    • When you validate the squash (you leave interactive mode), Git will re-apply the commits in the same order as they were configured just before. We then put in a commit message relating to the grouping of our commits (from the messages for the relevant commits) and that's all.
  • When the final commit is pushed, you need to force it: git push --force