A short introduction to version control with git
Folder name: gitintro
One-time extra-special due date: you can have until Saturday 9/17 for this one
You will work with one or two partners assigned to you for this assignment. Do the individual work on your own computers, but share a single git repository for your project. Put all collaborators' names in the comments at the top of each source file.
Goals
To learn about:
- version control systems in general
- using the git version control system to collaborate with another person
- a few essential git operations: clone, status, add, commit, pull, push
Summary of your tasks
Here's the quick summary of your tasks. Much more detailed instructions are in the numbered sections below.
- Before getting started, make sure you have completed all the steps in the development environment setup assignment.
- Choose one partner's GitHub repository in which to do your team's work for this assignment. This partner will be named "Alice" for this lab.
- Create a top-level directory called "gitintro" in your chosen repository, and a simple hello, world Python program called hello.py in the gitintro directory.
- Add some items to the .gitignore file in your repository.
- Once your simple hello.py is done, each partner should modify the code in some way. In the process, you will use the git commands that allow multiple people working on different machines to collaborate on shared code. See the adventures of Alice and Bob below.
0. Detailed instructions (featuring Alice and Bob)
The rest of this document contains lots and lots of details. Go slowly, write down your questions as you go, and pay attention to error messages and other information that appears on your screens. Also, talk to your partner about each step: Did you understand what happened there? Should we try something different? Should we reread the instructions? What does that sentence mean? Maybe we should bug Jeff or post on Slack about this one. etc.
If you get stuck or just want a little elaboration on a concept, don't hesitate to ask for help, in class, in office hours, or on Slack.
For the rest of this document, and sometimes in other exercises, I will refer to the partner whose repo you're using for this project as Alice, and each other partner as Bob. This makes writing instructions a lot easier than referring to "the partner whose repo you're using for this project" and "the partner whose repo you're not using for this project". Alice and Bob have been used in computer-related exposition for a long time because they love communicating collaboratively and they're handy to have around.
Have fun!
1. Decide who's going to be Alice, and who is going to be Bob
If three of you are working together, pick Alice and then the other two people can be Bob1 and Bob2, and they can both do Bob's tasks.
2. Alice & Bob: look at Alice's CS257 repository on GitHub
Go to GitHub, login, and click on your cs257 repository. At your repo's home page, you should see a display showing the files in the repository. Right now, that's probably just README.md, maybe LICENSE if you added a license, and .gitignore.
A repository is essentially a folder in which you can store whatever files and subfolders you want. What makes a repository more than a folder, however, is that the version control system (git, in this case) keeps track of all the changes that get made to the files in the repository. This saving of history makes it possible for you to retrieve old work, track down the time when a bug was introduced (and who introduced it), collaborate on a project with a team of programmers, easily back up your work, etc. Version control systems are a bit of a hassle to learn for the first time, but they're indispensable programming tools and unquestionably worth the effort.
3. Alice: grab a local clone of your repository
Go to your repository's page on GitHub. There should be a big green button labeled "Code". Click it, and copy the URL that appears in the resulting popup window. You might be able to choose between a coupl URLs at this point; pick the one that starts with https.
Right now, your repository is stored only on the GitHub server. To add files to it, you'll need to clone a copy of the repository onto your working computer. You will then add files to your local copy of the repository and eventually, you'll manually push your changes back up to GitHub.
Create your clone like so:
- Open a Unix terminal
- cd to wherever you want to store your repository's clone
- Execute this command:
git clone https://github.com/...where the "..." is the remainder of the link you just copied from the Code button.
You should now have a folder called "cs257" (or whatever you named your repository). This folder should contain README.md, maybe LICENSE, .gitignore, and a subfolder called .git. You can move cs257 wherever it's convenient for you to have it. (Curious about the contents of the .git folder? Go ahead and poke around to see what's there. It gets more interesting, of course, after you add some files.)
IMPORTANT FOR WINDOWS USERS: When you do this, you will need to be careful about where you put your files. If you put your repository inside the Linux file tree (by, say, doing "cd" at the terminal prompt to get to your Linux home directory and then doing "git clone ..." to put your git repository there), you'll run into file permissions trouble if you try to access your files using a Graphical User Interface (GUI) tool like VS Code or Brackets or Sublime or Notepad. There's a simple solution. You can use your terminal to access files in the normal Windows file system (say, on your C drive) by doing this:
4. Alice: add Bob as a collaborator on your repo
- Go to your repo on github.com
- Click on the Settings gear icon
- Select Collaborators on the left-side menu
- Click the Add People button and add your lab partner's github account
5. Bob: get a clone of Alice's repo
Once Bob is a collaborator on Alice's repo, Bob should git clone it to their
working machine. You can add an extra argument to the clone command to name the new repo
in a way that you'll remember it's Alice's repo:
6. Alice: add a little bit of code
- (Bob, you're not typing, are you? Bob, you're paying attention to what Alice is doing, right? Stop typing, Bob! It's not your turn yet.)
- OK, Alice: at the top level of your repo, create a folder called gitintro.
- Using a text editor, create a hello-world Python program hello.py inside the gitintro folder. Test it to make sure it runs correctly.
Once you're happy with your hello.py, save it, and then do the following. Go nice and slow, and study and discuss with Bob the output git generates at each step before you move on:
cd cs257/gitintro git status git add hello.py git status git commit -m "Added the hello.py program" git statusNote that those three "git status" invocations are there because I want you to see the status messages before and after the "git add". This sort of exploration is part of coming to understand how git works, but it's also something I often do myself to make sure I don't make big changes too fast. Going a little bit slowly like this saves me a lot of hassle in the long run.
- Open up your GitHub repository in a web browser. Take a look at the files, if any, in the repo as stored on the GitHub server.
Now Alice should execute:
git pull git pushThe first time you do this, it's likely that your computer will ask you for your user name (i.e. the user name of your github account) and your "password". For the password, enter your Personal Access Token that you created in the setting up your development environment lab.
- Reload your GitHub web page. What, if anything, has changed?
- Talk with Bob about what each of those commands did.
What's the meaning of
git addandgit commit? What dogit pushdo? Ask around, search the internet, etc. We'll talk more about these commands as time goes on, but start now to try to understand these operations—don't just memorize them.
7. Bob: can you see Alice's changes?
(Alice? Hands off the keyboard. It's Bob's turn.)
Bob, at your terminal on your computer, cd to your clone of Alice's repository, and do
Does the hello.py file appear in your copy of the repo? It should. If it doesn't, try to figure out what went wrong, then ask for help if you're stuck.
8. Bob: make a change; Alice: get Bob's changes
Bob: Change something in hello.py (add a comment, add a print statement, whatever). Then do the git status/add/status/commit/push sequence from Alice's section above to get your changes included in the central copy on github.com. (Note that Bob will use Bob's PAT, not Alice's PAT in place of a push password, and because Alice added Bob as a collaborator on this repository, that will be good enough. Neither Alice nor Bob needs to know each other's PAT.)
Alice: do a "git pull" and see if you ended up with Bob's version of the code.
9. Bob: edit the .gitignore file
While we work on a project, it's common for the project directory to accumulate files that aren't really part of the project. For example, if you write program.py and module.py and program.py includes an "import module" statement, you may discover a module.pyc or a folder called __pycache__ in your working directory. This isn't source code, and it doesn't matter if you delete it—it'll just get recreated next time you "import module". So you don't want that litter included in your repository.
There are lots of other examples of files that shouldn't be saved in a repo. Like the .DS_Store files the macOS Finder generates whenever you look at a folder in a window or the .class files you get when you compile a .java file. Accidentally adding these files to your repository is all too easy. And since these files typically change every time you run the Python program or recompile the Java program or look at the folder in a window, all those changes get added to the repository every time you commit, which makes every clone of your repo take up a lot of unnecessary disk space. It's a mess, and we hate messes.
To prevent you from accidentally adding these extraneous files to your repository, you can tell git to ignore them completely via a .gitignore file. If Alice followed the setup instructions, she already has a .gitignore file full of weird stuff. Note that one line in .gitignore says "*.py[cod]" and another says "__pycache__/", which will cause git to ignore __pycache__ folders and .pyc, .pyo, and .pyd files.
To save macOS users a little pain, Bob is going to add the line ".DS_Store" to the .gitignore. .DS_Store files get created whenever you open a folder in the macOS Finder. You can delete them with no negative consequences, and you definitely do not want to include them in Alice's git repository.
- (It's Bob's turn. So Alice, you know what to do. Bob, carry on.)
Use a text editor to open .gitignore, and add these lines to it:
.DS_Store *.pyc __pycache__/- Add, commit and push your changes up to GitHub.
IMPORTANT ODDITY: by default, macOS, Windows, and Unix command shells don't display files whose names start with a period. So if you open your repo's top-level folder in a macOS Finder window, you probably won't see your .gitignore file. Similarly, a simple:
command at a Unix command line won't show you .gitignore. But this command does:
(the "-a" stands for "all").
10. Alice: retrieve Bob's changes to .gitignore
What's the command again?
11. Alice & Bob: try git log
Execute git log on both of your machines. What do you see?
What does it mean?
12. Alice & Bob: got a little time? Experiment.
Try just doing it all again, making small changes, adding files, etc., sending changes back and forth. Get comfortable with the basic edit/add/commit/pull/push workflow.
13. All done? Alice: delete Bob as a collaborator
It's good to keep your permissions as limited as possible. So even if you expect to work with Bob on the big project, you might want to delete them as a collaborator for the short term.
14. Yipee!
Congratualtions! You're using git.