MyTinyGit is a version control system which mimics some
basic features of Git
, as well as some additional
features.
Each commit is stored in a subdirectory with copies of every file.
-
Commit simply creates a new subdirectory then copies all added files to the subdirectory.
-
Checkout simply deletes everything in the current folder and copies all files from the requested subdirectory in their place.
-
Take too much space.
- To figure out which files to copy, we had to walk through the entire commit history starting from commit 1.
- Name different folder(v1, v2, v3...),
Hashmap <Commit, Name>
Look for previous commit and modify the file with this commit.
V1 Commit (Hello.java): Hello.java → v1
V2 Commit (Hello.java, Friend.java): Hello.java → v2, Friend.java → v2
V3 Commit (Friend.java, Egg.java): Hello.java → v2, Friend.java → v3, Egg.java → v3
V4 Commit (Friend.java): Hello.java → v2, Friend.java → v3, Egg.java → v3
V5 Commit (Hello.java): Hello.java → v5, Friend.java → v3, Egg.java → v3
- Two people commit at the same time, this previous commit is
N
. Who is going to be commitN + 1
? No center server! Buggy! - Use hashing to solve the name of commit (Extremely unlikely to have collision)
- Check if
.gitlet
file exists ingitlet init
- Init all folder with
mkdir
- make empty Staging area and initial commit
byte[] contents
File file
- Staging area is a list of added blobs
- Place to store is in staging folder by calling
writeObject
- Add persistence file to record staging history
private Map<String, String> addBlobs
private Set<String> rmBlobs
private Map<String, String> addBlobs
HEAD
is reference of branch file.Store that SHA-1 value under a simple name- HEAD (ref: refs/heads/branch?)(File Contents should name of branch File). Use
join
to refer to File in heads folder.
# Read HEAD file
$ cat .git/HEAD
ref: refs/heads/master
# Crude way of updating master
$ echo 1a410efbd13591db07496601ebc7a059dd55cfe9 > .git/refs/heads/master
# Safe way to update master
$ git update-ref refs/heads/master 1a410efbd13591db07496601ebc7a059dd55cfe9
- Difference between a tree and a graph: Tree has root, therefore transverse from root to get to any node; Graph has paths. Start from a random node and dfs or bfs all the way with distance v.
- Find LCA (lowest(Regard to commit tree root: Initial commit) / latest common ancestor) for any two commits object.
- In
Staging
class, refractor storeBlobs fromList
that storeBlob
object to HashMap that map between <Blob pathName, SHA1-hash of Blob>. Easy to delete! - Still need Blob to quick read byte for diff or quick view file contents
/** This is buggy! Since these Blob objects are diffent!! */
/** Shared list to store blobs, add or remove file to storeBlobs in Staging area. */
public List<Blob> storeBlobs = new ArrayList<>();
/** Remove file in storeBlob list. */
public void rmFileInStaging(File fileName) {
Blob blob = new Blob(fileName);
storeBlobs.remove(blob);
}
- When Writing staged file to staging folder (BlobID diff from previous commit and current Staging).
Use
Utils.sha1(blob.getFilePath())
as staging file entry name(String), easy to overwrite if file is already staged. - Be careful with object referencing! Return copied new object.
- Use
TrieIndex
to speed up its search for abbreviatedcommitID
- When check for existence in blobID, use
getOrDefault
to define value if key does not exist. MergeCommit
has itssaveBlobs
. Its contents are only relevant withparentCommit
andcurStage
. Checkout files are staged andadd
.- Use bfs to get LCA Commit.
- IntelliJ provides a feature called “remote JVM debugging” that will allow you to add breakpoints that trigger during integration tests.
- The script that will connect to the IntelliJ JVM is
runner.py
# Setup for dubgging
# nano ~/.bashrc
# export MY_TINY_GIT=/home/chris/MyTinyGit
# Activate
# source ~/.bashrc
# echo $MY_TINY_GIT
make
cd /home/chris/Desktop/MyTinyGit/testing
python3 runner.py --debug samples/test36a-merge-parent2.in
- Print my output in testing folder
cd /home/chris/Desktop/MyTinyGit
make
make check TESTER_FLAGS="--verbose"
- Test specific test
make
cd /home/chris/Desktop/MyTinyGit/testing
python3 tester.py --verbose samples/test36a-merge-parent2.in
cd /home/chris/Desktop/MyTinyGit
find . -name "*java" | xargs cat | wc