Skip to content

Latest commit

 

History

History
292 lines (180 loc) · 18.2 KB

File metadata and controls

292 lines (180 loc) · 18.2 KB

Using Git/GitHub in Scientific Collaborations - tutorial

In this tutorial, you will use Git and GitHub to set up your own GitHub repository, add and remove files, clone a remote repository (the one you are in right now), and synchronise it to your account. Finally, you can try to add each other as collaborators.

If this is your first time using Git, it is a good idea to check that you have done the configuration. See the setup guide

Note that code in < > brackets should be replaced with the text that applies to you without the brackets. Everything else is copy/paste friendly.

1) Setup a repository

For the first exercise, you shall create a new repository with GitHub, initialise a local folder, set up the remote link between the GitHub folder and the local folder, and finally pull the remote folder.

Step 1: Go to your GitHub page. Click Repositories and then click the green New button. This will take you to the repository creation page. The repository that you are about to create will only be used for this tutorial (unless you want to keep using it for something else that is up to you), so it does not matter what you call it. As a general tip, try to keep the titles short and informative. I suggest that you call it Github-crash-course.

You then have the option to write a short description of the repository. This text is only for your GitHub page. It is nice to add one or two sentences that describe what this repository is for.

Then you have to select privacy settings for the repository. Your options are:

  • Public: The repository is visible to anyone on the internet.
  • Private: Only you and any collaborator you add to the project can see the repository's content.

You can always change the privacy setting for the repository later in the settings menu.

You then have some options to create the repository with some files already present. README.md will create the README file that is shown on the front page. .gitignore is a text file in which you can specify files in your folder that should not be tracked by Git once you start committing files. Licence lets you choose from among different open-source licences. You can choose what you want, but you can also add these later.

For now, create the repository with only a README file.

Spend a few minutes clicking around on the different menus in your newly created repository to see what you can do. Can you find the place where you add collaborators?

Step 2: Initialise the local folder: go to the file path where you want the project to be saved on your local computer. Create a folder for the tutorial; call it, e.g., Github-crash-course. Make sure that you always have a folder dedicated to your new project. Do not initialise Git directly in your home directory.

Open the new folder in a terminal. In Windows, you can open the folder, right-click anywhere, and open Git Bash here. A terminal window will appear. Type

git init

The folder is now declared a git folder.

Step 3: Next, you should set up the remote. Find the link for the repository on the GitHub page:

Copy the link address. Then, back in the terminal, you write:

git remote add origin <the link>

You can check which remotes you have set up for the repository with this command:

git remote -v

Step 4: With the remote setup, the last step is to pull the remote files.

git pull origin main

You should now see the README file in your local repository.

Tip: you can also run git init in folders that already have files in them, e.g., if you have a project you are working on that you want to upload to GitHub. The procedure is the same. You can then add the existing files, as you shall see in the next step.

2) Synchronize files

With the project setup, you are ready to work on your scripts in the folder. Working on your code is no different than before; Git has no impact on this. In case you are working on a project on different computers or working in collaboration, it is always good to start by pulling the latest changes as you did above with git pull. Once ready, you do your edits to your scripts.

For now, make a new text document in the project folder. Add some text to the document. If you do not know what to write in the file, list your top ten favourite animals.

When you are done, you stage the files you want to commit.

Tip: Terminal-based programs, including Git, can have trouble dealing with files with blank spaces in the filename. Use underscores instead. Instead of My File.txt, call it myFile.txt or My_File.txt.

Also note that EVERYTHING is case sensitive.

Step 1: Add your changes to the stage. Adding or removing files to the stage does not change the files or upload them right away. You can freely add and remove files at this point. It is not until you commit that the changes are made. Remember that the stage is like a box where you can put and take as many items in and out as you want. But when you commit, you seal the box and send it by post.

Add the file to the stage:

git add <my_file.txt>

Check the status of the stage to see what has changed since the last commit:

git status

You should see the filename in green under changes to be committed.

Next, edit the README file, e.g., describe what you wrote (ten favourite animals) in the text file. Check the status again. You should see the filename of the README file is in red under Changes not staged for commit. These are the files tracked by Git and have been changed but not staged yet. You can stage all changes with git add -u (for adding all Un-staged changes).

Any files and folders in white at the bottom are not tracked by Git, and it will not know if they are changed or not. you first need to add them with git add <filename>

Step 2: Commit the changes. Check the status. If the files and changes in the staging area are like you want them, you are ready to commit. Remember to write a useful commit message after the flag -m (for message). Begin and end with " ". In case you do not specify the -m flag, it will open the default terminal text editor (in most cases Vim) to remind you to write the commit message gently! It is easier to use the -m flag.

git commit -m "list of ten favourite animals"

Step 3. Now push the commit to the remote:

git push origin main

Go to the repository on your GitHub page (refresh if you already have it open). You should now see your new folder. If you do, then congratulations. You now know how to push/pull files.

Now, try to remove the file you just created. Go back to the terminal. Use git rm to remove files:

git rm <my_file.txt>

Look in your folder again. The file is now gone! git rm deletes files permanently with no warning. Too bad if you wanted to keep that file or you removed it by mistake! In case you want to keep the file, use the extra flag --cached like this:

git rm <my_file.txt> --cached

Knowing this would have been useful before you were told to delete the file! Now, do you dare to add all changes (git add -u) and commit the changes before you go to the next step?

3) Revert to an earlier version

Let's see if we can restore the deleted file. Since you have not committed the changes yet, you can go back to the latest commit:

$ git reset --hard HEAD

Did this restore the deleted file? If you committed the changes after deleting the file, it would be part of the latest commit. In that case, you must find a previous commit to revert to. First, you must find the commit id number of the commit. Use git log to get a list of all commits. You will see that each commit has a long gibberish number like this: 9fb4a.... Copy the number of the commit you want to return to and use it like this:

$ git reset <the long number>

Check that you selected the correct commit. It can be useful to go back to your GitHub repository to get an overview of the changes in the various commits if you have many commits.

4) Get remote project

You do not have to start a project from scratch every time. In the next part, you shall pull the scripts from this tutorial. The easiest way to do this is by using the one-way clone option. Find the link for the remote repository and then clone it. This will pull the entire repository into a new folder called Github-crash-course.

git clone <remote url>

This is how you (usually) would get open-source toolboxes. You can then keep the toolbox up to date by pulling the developers' recent updates whenever they push the latest changes. You can, however, not push your changes directly back unless they make you a collaborator. What you can do is to make your own "fork" of the repository. Let's look at two ways to do this.

Option 1: Clone the remote folder. Then change the remote origin to the address for your GitHub repository:

git remote set-url origin <the link>

Use git remote -v to see the location before and after you redefine origin. This option might cause errors if you already have local changes.

Option 2: have multiple remotes. You can have multiple remotes beside origin. origin is not a Git function but the name we gave the remote when we defined it with git remote add (however, naming your main remote origin is the convention you will see all over GitHub, so use this name to make things easier for yourself and everybody else).

In the tutorial folder you created in the beginning, you specified origin as the GitHub repository on your account. Now, add a new remote that points to this tutorial repository. First, find and copy the URL similarly to when you cloned the tutorial repository before. Then, add this as a new remote to your terminal. By convention, we call this upstream.

git remote add upstream <the link>

See the remotes with git remote -v. Get the files from the remote to your local folder and merge them into your main branch.

git fetch upstream main
git merge upstream/main

What you just did was to fetch the upstream folder as a separate branch and then merge that branch into your main branch.

5) Working with branches

So far, you have only been working on one branch. Let's say that you want to implement a new analysis step, but you do not yet want it to be part of the code you present on your GitHub account. A solution is to create a new branch. You can see your current branches with git branch -a. The main function to managing branches is git checkout. Create a new branch by adding the flag -b (for new branch) like this:

git checkout -b <branch name>

Keep the branch name short, informative, and without blank spaces. Good examples might be bugfix or new-prepoc (short for "new preprocessing", something I do with EEG data more often than I like), depending on your reason for creating the new branch.

You can switch between branches with git checkout (without the -b flag).

git checkout <branch name>

If you get lost, use git git branch -a or git branch -v to see your branches with the one you are currently on highlighted. The output from git status also specifies as the first line which branch you are currently at and what changes you have in that branch.

Make it a practice to always check which branch you are in when you begin your work.

Working on a new branch

Now switch back to the new branch. If you merged, the remote should have the folder called friday_toolbox. The folder contains a single MATLAB/Octave file with a function. You can try to run the script if you have MATLAB or Octave (if not, it is just a text file, and you can open and edit it with any text editor). In short, the function finds today's day and returns the answer depending on the date.

Let's say you want to expand the function to take any date as input. See if you can make it work with the following code snippets. Define the input as varargin (default MATLAB for any input).

if ~isempty(varargin)
     day = varargin(1);
else                                    % This part is already in the script
    format shortg
    D = clock;
    day = [num2str(D(1)),'-',num2str(D(2)),'-',num2str(D(3))];
end

When you are done, add the changes to the stage, commit, and push. Note that you are no longer on the main branch when you push the changes. When you push, you should, therefore, not push to main but to the current branch:

git push origin <branch name>

You can also see the branches that you have pushed to your GitHub repository on the repository page with the branch drop-down menu. You can use the drop-down menu to switch between branches on the GitHub repository in the same way that you switch between branches locally with git checkout.

Merging branches

As a general rule, you do not want too many branches. When you finish the work that made you create the new branch, you should merge it into your main branch.

Option 1: Merge in the GitHub repository. When you look in the GitHub repository, you might have seen a message about the newly pushed branch:

When you bushed the new branch, GitHub automatically created a pull request, i.e., asking you to merge the new branch into main. Click the green button Compare & pull request. This will take you to a new page where you can finalise the merge. First, GitHub will tell you if there are any conflicts between the branches that you have to sort out first (i.e., if there are multiple changes to the same files independent of one another).

If there are no conflicts, you should write a short comment (similar to the commit messages) and, optionally, a more extended explanation to let your collaborators know what you did.

If you scroll further down, you will see an overview of the changes that will be merged. Click Create pull request to finalise the merge.

Since the branch is now merged into main at the remote repository, you can get the merged files by pulling the origin main as usual.

Option 2: Merge in your local folder. You can merge the branches locally if you do not want to push your new branch to your remote GitHub repository. First, use git checkout to switch to the branch that you want to merge into. Then, use git merge to merge the other branches.

git checkout main
git merge <branch name>

Git will tell you if there are any conflicts that you need to sort out. If not, the <branch name> is merged into your main branch.

Delete a branch

When you are done merging, you can delete the branch to keep it simple and avoid suddenly having a lot of unused branches with changes you forgot about.

Delete branch:

git branch -d <branch name>

Delete remote branches in your GitHub repository by clicking the branch drop-down menus and selecting View all branches. Then go to the overview of branches and click the garbage icon to delete the branch.

6) Collaborations

All of the above covers how to manage your project files. The next step is how to manage your collaborators. GitHub has many ways to define collaborations. The easiest and most straightforward way is to add your collaborators directly to the repository by giving them access. This is done at the repository level, so they will only have access to that repository and not anything else on your account.

First, you must ensure your collaborator has a GitHub account.

To grant your collaborator access, go to the Settings tab on the repository’s main page. Click Manage access in the menu on the left. Enter your password. This will give you an overview of who has access to the repository.

Click the green Invite a collaborator button.

A new window appears where you can search for your collaborators' GitHub username or email address. Click the green button to confirm.

If you are on the online crash course, return to the meeting. You will be paired up with another attendee in a break-out room. Try to complete the following tasks:

  1. Add each other as collaborators on each other’s tutorial GitHub repositories by giving each other access using the procedure described above.
  2. Get their code into a local directory on your computer. You might want to create a new folder. Then, set up a new remote (git remote add) that points to your collaborators's repository and pulls their code. Give the new remote an informative name (e.g., their initials).
  3. Add the text file from previously to their project. Commit and push the changes back to your partner's repository. This will create a pull request on their side, and their push will create a pull request on your side.
  4. Merge each other’s pull request

Note that working with repositories you do not own follows the exact same procedures as working on your own repositories. In practice, you would not be working on two different repositories in parallel unless they are two different projects. Keep one repository per project.

Summary

If you have completed the tutorial this far, you should know the basics of Git and GitHub. There is a lot more to learn and many features in Git and GitHub that this tutorial does not cover, and I encourage you to continue to explore further. However, what you have learned here is, in my experience, enough to manage your own analysis scripts and share code in scientific collaborations.

The next step is setting up a GitHub repository for your actual project. You can create those from scratch as shown above:

  1. Create the repository on your GitHub page.
  2. Initialise Git in your local folder. If you already have a local folder with scripts but want to get started with Git, create a repository on your GitHub page (without any README file or anything), and then initialise Git in the folder where you have your scripts.
  3. Add all the scripts that you want to track and keep synchronised.

It is unavoidable that you will encounter errors at some point. Do not despair; errors can be fixed! Try to go back to see what went wrong. Then, seek out solutions online. Git and GitHub have a vast user base. Someone has likely encountered the same error as you, posted about it somewhere, and found a solution.