Git Introduction to Git - EPFL-MICRO-315/TPs-Wiki GitHub Wiki

⚠ wiki page used in TPIntro

🐈 Introduction

Git is a worldwide professional tool used to version control projects. Such tools are essential when working in groups, as all members might have their local modifications and merging code inputs is an essential part in shaping software. This wiki page intends to introduce the fundamentals of git.

πŸ”­ Some theory

Commit history

  • In git, code is managed though a succession of commits (snapshot of the code) where the differences between commits if tracked;
  • By creating a branch, code can diverge in two different directions without influencing each other;
  • A merge is the fusion of 2 branches (e.g: fusion of the work of Bob and Alice)

    drawing

Workflow

Below you can find the typical workflow when using git.

drawing

Inspired by https://github.com/pushpankq/Git-Commands-

  • Workplace: files/folders directly accessible from your computer
  • Stagging area: temporary place where are added modified files before beeing committed
  • Local repository: local copy of the repository on your computer
  • Remote repository: repository on a server (e.g: Github, Gitlab, etc)
  • πŸ’‘ If you don't fully understand this part, don't worry the practical parts will help to clarify these concepts.

Remote

  • A remote is a repository hosted on a server, in opposite with the local repository hosted on your computer (thus only accessible by you);
  • It is possible to have multiple remotes linked to a single local repository, so pushing/pulling/fetching can be done to/from a variety of cloud repositories.

πŸ“‚ In practice: git repositories

Here below a video that sums up this part of the wiki with a command-line approach:

And a video that covers git and GitHub remotes through VSCode:

⚠ Pre-requisit

While this section mainly makes use of git through Command Line Interface (CLI), some git commands are completed in VSCode.

For students participating in the labs of MICRO-315: Install EPuck2 IDE, and read through Installing the IDE coresponding to your OS in the Wiki Sidebar.

πŸ‘‰ Initialising a git directory

  • Launch a terminal in the EPuck2_Workplace directory

    • on Windows, launch git bash (and not cmd or powershell) with right click in the right directory

      drawing

    • on Linux and MacOS, launch any terminal you prefer
  • If needed, create a new directory into the EPuck2_Workplace, then move into it

    mkdir GitIntro
    cd GitIntro
    
  • Initiate a git repository:

    git init
    
    • This command creates a hidden folder named .git/ containing all the informations/history of the repository that git needs or uses to handle its versioning control.
    ls -a
    
    output console:
     
    ./  ../  .git/
    

πŸ‘‰ Commits

  • Assume you have created some files, for example:

    # Creates a file named README.md with hello world written in it
    echo "hello world" > README.md
    # Creates a file named text1.c in a folder named src, and writes "//here is a text line" in the file
    echo "//here is a text line" > src/text1.c
    
  • Check the current status of your git repository

    git status
  • In preparation of the commit, stage all the files that you would like to include in your commit

    # To add all the files and folder modified in the current directory and subdirectories ending with .md
    git add *.md
    # To add every file and folder modified in the current directory and subdirectories
    git add *
    # Print the changes to be committed
    git status
    
    output console:
     
    On branch master
    

    No commits yet

    Changes to be committed: (use "git rm --cached ..." to unstage) new file: README.md new file: src/text1.c

  • Once you are content with the staged files/modifications, commit those to the local repository

    git commit -m 'Commit message, appears anywhere the commits are listed'
    

πŸ‘‰ Checking out between commits

  • First list the previous commits made in the current branch

    git log
    
    output console:
     
    commit 70680315a3116628e3c1ee48cd17682b1f8fb6c7 (HEAD -> master)
    Author: Marcus 
    Date:   Mon Sep 12 13:07:57 2022 +0200
    
    Created some files
    

    commit 0fb0af36998d734e94cc432a404ad72e09c639e6 # the commit we want to roll back to Author: Marcus [email protected] Date: Mon Sep 12 13:03:05 2022 +0200

    First commit!
    
    • the long string after commit is the commit's unique ID/hash, in this case 0fb0af36998d734e94cc432a404ad72e09c639e6 (yours will be different)
  • To roll back to a given commit

    git checkout 0fb0af36998d734e94cc432a404ad72e09c639e6
    ls -a
    
    • The repository will now have the same content it had at the time of the commit
  • To return to the latest commit on branch master (the tip of the branch)

    git checkout master
    
    

πŸ‘‰ Branches

  • To create a branch

    # Creates a new branch called "my_branch" and switches to it
    git checkout -b my_branch
    
    • You can see with ls that this branch has the same content (files and folder) of the branch you were in before
  • To switch between branches

    # Switches to the branch master, if it exists.
    # The checkout command is very general as it can also be used to checkout to specific commits
    git checkout master
    # Switches to the branch master, if it exists.
    # The switch command is specific to branches and can be used for better clarity.
    git switch master
    

πŸ‘‰ Merging branches

  • Suppose you have the following changes between two branches:

    git checkout master
    echo "void main(char argc, char **argv) {}" >> src/text1.c
    git add *
    git commit -m 'Marcus added the main function with arguments'
    
    git checkout my_branch
    echo "int main() {}" >> src/text1.c
    git add *
    git commit -m 'Luisa added the main function'
    
  • To merge the changes made by Luisa with the changes made by Marcus in the master branch:

    ⚠ It is IMPORTANT to be on the branch where the merge must by applied BEFORE merging!!

    git checkout master # Because we want the result to be on master
    git merge my_branch
    
  • Either your merge will be completed, or you might have conflicts:

    output console:
     
    Auto-merging src/text1.c
    CONFLICT (content): Merge conflict in src/text1.c
    Automatic merge failed; fix conflicts and then commit the result.
    
    • It's perfectly normal to have conflicts when the same file has been modified differently on the two branches
  • Solving merge conflicts can be done easily through VSCode, as it offers a much better view over the files

  • Launch VSCode_EPuck2, open your git folder, and you should see "!" marks next to some of your files or foders

    drawing

    • As you can see:
      • Markup 1 indicates that there is change in the folder src;
      • Markup 2 indicates that there is 1 "problem";
      • Markup 3 confirms that there is 1 conflict.
  • Click on Resolve in Merge Editor

    drawing

    • Markup A indicates that the file text1.c is now in mode Merging, now displaying 3 "sub-tabs":
    • Sub-tab 1 contains the incoming branch to merge: my_branch in our case;
    • Sub-tab 2 contains the branch where the merge must be applied: master in our case;
    • Sub-tab 3 displays the result of the merge, at this time everythin except the conflictual sections of the code.
  • In our example the right code should be a mix between both: The type of main function should be int but the function should have arguments. To mix both changes, click Accept Combination above the conflictual code in sub-tab 1 or 2. If you want to confirm changes from one or the other branch, click on Accept Current or Acept Incoming;

  • The sub-tab 3 displays the actual result, and it accepts manual modifications for you to obtain the right final code as below:

    drawing

  • Once the result is satisfactory, the Complete Merge button can be pressed to validate the changes;

    drawing

    • The result of the merge being a commit, it is possible to change its default message;
    • Finally, clicking Commit will locally commit the merge.
  • Once the merge is comitted, it appears in the repository git graph:

    drawing

🌍 In practice: GitHub repositories

⚠ Pre-requisit

  • Own a Github account

πŸ‘‰ Creating a GitHub repository

  • Once logged in on https://github.com/, repositories can be created eiher from your profile or from an organization by clicking the Repositoriestab then clikcing New;

    drawing

    drawing

  • You need to provide a repository name, visibility and preconfigurations such as a .gitignore template, README file and license.

πŸ‘‰ Adding a GitHub repository as a remote to a local git directory

When working on a local git project, you may want to share your code with others for collaboration. To do this, you need to link your local git directory with a remote GitHub repository. To do this:

  • Launch a terminal in the EPuck2_Workplace/GitIntro directory

    • on Windows, launch git bash (and not cmd or powershell) with right click in the right directory

      drawing

    • on Linux and MacOS, launch any terminal you prefer
  • Add a remote pointing to the newly created github repo to the exist repo GitIntro

  • ⚠ Replace 'username' with the one you have under GitHub

    git remote add origin https://github.com/username/GitIntro.git
    # Push all branches to the remote origin
    git push -u origin --all
  • The GitHub repository should now contain the content of your local git directory:

    drawing

    • πŸ’‘ 1 Here you can select and manage branches
    • πŸ’‘ 2 Here you can see the content of the selected branch/commit
  • The git project can now be clone wherever you want by using the command:

    # Clone the repository into a new folder called GitIntroCopy
    git clone https://github.com/<<username>>/GitIntro.git GitIntroCopy

Git - Index

  • git clone <url>: Clone (download) a repository that already exists on GitHub, including all of the files, branches, and commits
  • git status: Always good to use, this command shows you what branch you're on, what files are in the working or staging directory, and any other important information
  • git branch: This shows the existing branches in your local repository git branch : Create a branch from your current location
  • git branch –all: See all branches, both the local ones on your machine, and the remote tracked branches
  • git checkout <branch-name>: Switches to the specified branch and updates the working directory
  • git add/rm <file>: Snapshots the file in preparation for versioning, adding/removing it to the staging area
  • git commit -m '<descriptive message>': Records file snapshots permanently in version history
  • git fetch: Updates your current local repository branch with all new commits from the corresponding remote branch on GitHub
  • git pull: Updates your current local working branch with all new commits from the corresponding remote branch on GitHub git pull is a combination of git fetch and git merge
  • git push: Uploads all local branch commits to the remote
  • git log: Browse and inspect the evolution of project files
  • git remote -v: Show the associated remote repositories and their stored name, like origin
  • git reset <file>: Unstage a file while retaining the changes in working directory
  • git diff: diff of what is changed but not staged
  • git diff --staged: diff of what is staged but not yet committed
  • git merge <branch>: merge the specified branch’s history into the current one
  • git reset –-hard <commit>: clear staging area, rewrite working tree from specified commit
  • git config -–global user.name β€œ<username>”: set a name that is identifiable for credit when review version history
  • git config -–global user.email β€œ<email>”: set an email that will be associated with each history marker
  • .gitignore: a file specifying any file/folder to be ignored when staging modifications
  • origin: name given by default to the remote from which the repo was cloned.

POSIX Shell - Index

  • mkdir <path>: creates a new directory under <path>
  • echo <string>: print to the terminal the <string> text, this output (as any command line command) can be redirected to a file using > or >>
    • echo "hello world" > output: overwrite the content of output file with string hello world
    • echo "hello world" >> output: append to the end of output file the string hello world
  • cat <path>: print to the terminal the content of <path>, can be redirected as well
  • ls -a: display the content of the current directory, display also the hidden files/folders

πŸ’‘ Further readings

⚠️ **GitHub.com Fallback** ⚠️