git
in ECE
3700git
is forgit
is a
revision control system that is heavily used in
software and computer engineering. It keeps track of file changes,
allows sharing among multiple developers, and handles merges when
changes are made by multiple people simultaneously.
In ECE 3700 we will use git
to coordinate
digital design assignments between students and the instructor. The
instructor will have a synchronized copy of each student’s files, so
that the instructor can efficiently track student progress and provide
assistance with the assigned tasks.
The instructor will maintain a central git
repository containing all the assignments for the semester.
Each student is provided with a fork repository that is
initially a copy of the instructor’s version. When a student works on an
assignment, they commit and push their
files onto the server. The instructor will regularly
pull students’ changes to stay synchronized.
In this assignment, students will:
git
commandsgit
The first thing you need is a terminal emulator capable of running
git
and
ssh
. Setup
instructions are provided in a separate document. Make sure you are
comfortable using the terminal before continuing with this assignment.
Practice basic tasks like directory listings with ls
, changing
directories with cd
, creating
directories with mkdir
, and so
on.
Test the git
command by
running
git --version
You should see a version number. If you instead see a “command not found” or similar message, then something is wrong with your setup.
You should receive personal account credentials include a
username and password that can be used
both for remote server access and for git
access. To
download a copy of your gitting_started
repository, follow this procedure:
On your computer, create a directory to contain git
repositories.
I call mine ~/gitclones
and
created it with the command
mkdir ~/gitclones
Change into your gitclones
directory using
cd ~/gitclones
Now download your clone using the git clone
command:
git clone https://username:passwd@left.engr.usu.edu/git/username/gitting_started
In this command you should replace username
with
your actual username, and replace password
with
your actual password. So if your username is dill
and your
password is pickle
, you would
type:
git clone https://dill:pickle@left.engr.usu.edu/git/dill/gitting_started
cd gitting_started
cd ~/gitclones/gitting_started
Before making edits, you need to configure your Real Name and Email Address. This is so that when you share your edits on the server, other users (i.e. the instructor) can easily see who you are. To edit your identity, type the following line in the terminal and press Enter:
git config --global --edit
This will bring up a terminal-based text editor with the identity
configuration file. By default, the text editor is vim
. At
first, vim
opens in read-only mode. To make edits, you need to press i
. When finished
with edits, you press ESC
. To save the
file and exit, you type the command sequence :x
(two
keypresses, then Enter).
An example configuration is shown below. Make edits to set your identity, then save and exit.
# This is Git's per-user configuration file.
[user]
# Please adapt and uncomment the following lines:
name = Dill Pickle
email = dillpickle@aggiemail.usu.edu
Summary of some vim
editing
commands:
i
| “insert” |
start editing |ESC
|
“cancel” | stop editing |u
| “undo”
| undo last edit (need to ESC
first)
|:w
|
“write” | save the file |:x
|
“save/exit” | save and quit |:q
| “quit”
| quit without save |Many power users like to use vim
. I don’t.
Many like myself prefer to use emacs
, others may
prefer a GUI editor like Notepad. You can change the default editor by
running this command:
git config --global core.editor "<command name>"
So for me, I would use the command name "emacs"
.
After changing your editor, test the change by repeating the
git config --global --edit
command, to make sure you did it right.
In your cloned repository, do a directory listing using ls
. You should
see a file called file.txt
. Open
the file with a text editor, make some changes, and
then save the file. In your terminal, type
git status .
The command output will look like this, indicating that file.txt
has been
modified:
On branch main
Your branch is up to date with 'origin/main'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: file.txt
no changes added to commit (use "git add" and/or "git commit -a")
Next, using the terminal, create a new text file using the cat
command:
cat > newfile.txt
Type some words. When finished, press Enter for a new line, then type
Ctrl-D
to
close the file.
Next, type
git status .
You should see output like this:
On branch main
Your branch is up to date with 'origin/main.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: file.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
newfile.txt
no changes added to commit (use "git add" and/or "git commit -a")
The status message reports that newfile.txt
is
untracked, meaning that it is not part of the
repository, it’s history is not recorded and it is not shared with the
server.
To include this file in your repository, use the git add
command:
git add newfile.txt
Then run a git status .
check again and you should see:
On branch main
Your branch is up to date with 'origin/main'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: newfile.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: file.txt
This indicates that git
is aware of
newfile.txt
and will include it in repository actions from now on.
After making changes and adding files, the changes are not
yet confirmed. To make them official, you need to commit
them to the repository:
git commit . -m "Type a brief message describing what was changed."
You can review the commit by running
git log --name-status HEAD^..HEAD
It should show an output like this:
Author: Dill Pickle <dillpickle@aggiemail.usu.edu>
Date: Wed Dec 23 10:26:02 2020 -0700
Made a new file, edited an old file.
M file.txt
A newfile.txt
After committing changes, the commit still needs to be shared
with the server and other users (i.e. the instructor). To do
this, you push
your commit
to the server:
git push origin main
It will printout a technical message tallying all the changes sent to the server. The last few lines should look something like this:
Writing objects: 100% (6/6), 2.60 KiB | 2.60 MiB/s, done.
Total 6 (delta 3), reused 0 (delta 0), pack-reused 0
To https://left.engr.usu.edu/git/dillpickle/gitting_started
945d1e8..873f856 main -> main
The two random-looking strings are version hash
strings, which serve as unique identifiers for every commit
. The push
output only
shows the first seven characters of the hash, but is enough to identify
the revisions in your own commit
history.
View the history by running git log
in the
terminal. The top entry should look like this:
commit 873f856b806a00a515a54f71a65ff833cd56201c (HEAD -> main, origin/main)
Author: Dill Pickle <dillpickle@aggiemail.usu.edu>
Date: Wed Dec 23 10:26:02 2020 -0700
Made a new file, edited an old file.
After the word commit
you should
notice the string 873f856
. This
matches the hash code reported for your most recent push
. The line
also indicates -> main, origin/main
,
which informs you that this commit
was push
ed to the
server.
For this tutorial, when you make a commit the server will respond by
appending an automated message to newfile.txt
. This
simulates a remote edit made by the instructor or
another user. To see if there are new changes on the server, run
git remote show origin
This command will list some basic details about the server repository. You just need to look at the last line:
main pushes to main (local out of date)
The key phrase here is local out of date. This means there is new data on the server. To download it, run
git pull origin main
The output will look something like this:
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (3/3), 296 bytes | 296.00 KiB/s, done.
From https://left.engr.usu.edu/git/dillpickle/gitting_started
* branch main -> FETCH_HEAD
873f856..9d45e00 main -> origin/main
Updating 873f856..9d45e00
Fast-forward
newfile.txt | 2 ++
1 file changed, 2 insertions(+)
The last few lines indicate which files are changed.
After pull
ing changes
from the server, you can see exactly what was changed using the git diff
command:
git diff HEAD^ HEAD
This runs a diff
command to
compare your most recent version (HEAD^
)
against the current version (HEAD
).
The output will look something like this:
diff --git a/newfile.txt b/newfile.txt
index 9472d00..a10b0c8 100644
--- a/newfile.txt
+++ b/newfile.txt
@@ -1 +1,3 @@
here is new file.
+
+I see you. You are seen.
The @@
symbols indicate the location of the edit: @@ -1
indicates the first line of file1 (from the HEAD^
commit),
and +1,3 @@
indicates the first line of file2 (from the HEAD
commit),
continuing for three lines. Lines beginning with +
are newly added
in the latest revision.
From time to time, the instructor will deploy new material or
corrections in the upstream repository. To merge these
updates, you need to run git fetch
and
git merge
:
git fetch upstream
git checkout main
git merge upstream/main
This will download any new material and merge it into your local repository.
Open file.txt
and make
some random edits. Now suppose you regret making those edits and want to
revert back to the last commit. The quickest way is to use git restore
:
git restore file.txt
Now view the contents of file.txt
using
the command cat file.txt
, and
you should see it has returned to its original condition.
If you find that you’ve made a complete mess in your local repository, you can restore everything by running
git restore
Now suppose you made a commit
with bad
changes. You can reset your repository to an earlier
version using the hash code. Let’s simulate this process.
file.txt
.git commit file.txt -m "made random edits"
git push origin main
git log file.txt
The log output will look something like this:
commit 68844b7449c41876bd0ed70705f060b27f449c02 (HEAD -> main, origin/main)
Author: Chris Winstead <chris.winstead@usu.edu>
Date: Wed Dec 23 11:30:31 2020 -0700
random edits to file.txt
commit 873f856b806a00a515a54f71a65ff833cd56201c
Author: Chris Winstead <winstead@trusty.hopto.org>
Date: Wed Dec 23 10:26:02 2020 -0700
Made a new file, edited an old file.
The top commit
is the one
we just did, with the random edits. But we regret this and wish we could
go back to the way things were. We can rollback the file using git checkout
like
this
git checkout 873f856b file.txt
This replaces your version of the file with the one from 873f856b… (you don’t need the entire hash code to identify the version).
To rollback the entire project, you can
stash your edits and run git revert
like
this:
git stash
git revert 873f856b
Resolving a merge conflict: At this point, it’s
possible that file.txt
had
edits in both HEAD
and 873f856
, and
git
doesn’t
want to make important decisions for you. Run git status
in the
terminal to reveal any merge conflicts. The output may look like
this:
Unmerged paths:
(use "git restore --staged <file>..." to unstage)
(use "git add <file>..." to mark resolution)
both modified: file.txt
This indicates that file.txt
has
ambiguous edits. Open file.txt
in a
text editor, and you will see this:
This is a file. Congratulations.
<<<<<<< HEAD
argle bargle
=======
>>>>>>> parent of 873f856... Made a new file, edited an old file.
In this file, git
indicates the
version differences between the <<<<<<
and >>>>>
lines. You need to decide what to keep and what to delete. Edit the file
as you like, and when you are finished use git add
to
resolve the merge conflict:
git add file.txt
git commit . -m "Got file.txt back how I like it."