Version Control System: Git#

Software development is repetitions of coding, testing, and improving. A version control system (VCS) allows

  • parallel development of parts and re-integration

  • trace back to previous versions when a problem is detected

Git#

The most popular VCS today is Git, created by Linus Torvalds for developing Linux.

If git has not been installed, follow one of these to install.

Mac:

  • Install XCode from the App Store

  • or install XCode Command Line Tools by xcode-select --install

  • or install HomeBrew and run brew install git

Windows:

Detailed documentations can be found at https://git-scm.com/docs

Starting a repository#

In your working directory, you can start a new repository by git init

Here we use an example of a directory containing a python module cell.py that we created in Chapter 4.

%mkdir cell
%cd cell
mkdir: cell: File exists
/Users/doya/OIST Dropbox/kenji doya/Python/iSciComp/cell
%%file cell.py
"""Classes for cells"""

import numpy as np
import matplotlib.pyplot as plt

class Cell:
    """Class for a cell"""

    def __init__(self, position = [0,0], radius=0.1, color=[1,0,0,0.5]):
        """Make a new cell"""
        self.position = np.array(position)
        self.radius = radius
        self.color = color
     
    def show(self):
        """Visualize as a circule"""
        c = plt.Circle(self.position,self.radius,color=self.color)
        plt.gca().add_patch(c)
        plt.axis('equal')

if __name__ == "__main__":
    c0 = Cell()
    c0.show()
    plt.show()
Overwriting cell.py
%pwd
'/Users/doya/OIST Dropbox/kenji doya/Python/iSciComp/cell'

Try running this code.

%run cell.py
_images/b9abdcf388f047ef3806da207633072df754e861b71586ebccd6fcddaadb4976.png

Now we create a new repository.

!git init
Reinitialized existing Git repository in /Users/doya/OIST Dropbox/kenji doya/Python/iSciComp/cell/.git/

This creates an invisible folder .git for book keeping.

%ls -a
./           ../          .git/        __pycache__/ cell.py      gcell.py
# The contents of .git folder
%ls .git
COMMIT_EDITMSG  config          index           objects/
HEAD            description     info/           refs/
ORIG_HEAD       hooks/          logs/

You can check the status of the repository by git status

!git status
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	__pycache__/

nothing added to commit but untracked files present (use "git add" to track)

Staging and Commiting files#

You can use git add to add files for staging.

And then git commit to register a version.

commit

!git add cell.py
!git status
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	__pycache__/

nothing added to commit but untracked files present (use "git add" to track)

Register the current version by git commit with a message by -m.

!git commit -m "initial version"
!git status
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	__pycache__/

nothing added to commit but untracked files present (use "git add" to track)
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	__pycache__/

nothing added to commit but untracked files present (use "git add" to track)

Registering changes#

After editing a file, you can register a new version by git add and then git commit.

Please edit cell.py or add another file to the directory and check the status.

!git status
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	__pycache__/

nothing added to commit but untracked files present (use "git add" to track)

Use git add to stage updated files.

!git add cell.py
!git status
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	__pycache__/

nothing added to commit but untracked files present (use "git add" to track)

And the git commit the changes

!git commit -m "cell.py updated"
!git status
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	__pycache__/

nothing added to commit but untracked files present (use "git add" to track)
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	__pycache__/

nothing added to commit but untracked files present (use "git add" to track)

You can see what was changed by git show.

!git show
commit ada6e011b864c93c202a176b18ab3b01db8f4801 (HEAD -> main, myBranch)
Author: Kenji Doya <doya@oist.jp>
Date:   Mon Dec 16 14:54:00 2024 +0900

    added gcell.py

diff --git a/gcell.py b/gcell.py
new file mode 100644
index 0000000..cd7b2a5
--- /dev/null
+++ b/gcell.py
@@ -0,0 +1,25 @@
+"""Classes for cells"""
+
+import numpy as np
+import matplotlib.pyplot as plt
+import cell
+
+class gCell(cell.Cell):
+    """Class of growing cell based on Cell class"""
+    
+    def grow(self, scale=2):
+        """Grow the area of the cell"""
+        self.radius *= np.sqrt(scale)
+        
+    def duplicate(self):
+        """Make a copy with a random shift"""
+        c = gCell(self.position+np.random.randn(2)*self.radius, self.radius, self.color)
+        return c
+
+if __name__ == "__main__":
+    c0 = gCell()
+    c0.show()
+    c1 = c0.duplicate()
+    c1.grow()
+    c1.show()
+    plt.show()

You can check the revision history by git log

!git log
commit ada6e011b864c93c202a176b18ab3b01db8f4801 (HEAD -> main, myBranch)
Author: Kenji Doya <doya@oist.jp>
Date:   Mon Dec 16 14:54:00 2024 +0900

    added gcell.py

commit fba656aec31be16236f9de2b429e91fac5ef7b2a
Author: Kenji Doya <doya@oist.jp>
Date:   Mon Dec 16 14:53:57 2024 +0900

    initial version
!pwd
/Users/doya/OIST Dropbox/kenji doya/Python/iSciComp/cell

Branch#

You can create a new branch to update the codes while keeping the current version untouched.

After creating a branch, switch to that branch by git checkout.

!git branch myBranch
!git checkout myBranch
fatal: a branch named 'myBranch' already exists
Switched to branch 'myBranch'

Now let us add a new module gCell.

!git status
On branch myBranch
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	__pycache__/

nothing added to commit but untracked files present (use "git add" to track)
%%file gcell.py
"""Classes for cells"""

import numpy as np
import matplotlib.pyplot as plt
import cell

class gCell(cell.Cell):
    """Class of growing cell based on Cell class"""
    
    def grow(self, scale=2):
        """Grow the area of the cell"""
        self.radius *= np.sqrt(scale)
        
    def duplicate(self):
        """Make a copy with a random shift"""
        c = gCell(self.position+np.random.randn(2)*self.radius, self.radius, self.color)
        return c

if __name__ == "__main__":
    c0 = gCell()
    c0.show()
    c1 = c0.duplicate()
    c1.grow()
    c1.show()
    plt.show()
Overwriting gcell.py
!ls
__pycache__ cell.py     gcell.py
%run gcell.py
_images/f8977b05443c3c14b152094884665a14d6dae4cd078833e0b55d6ea66c350e26.png

Then git add and git commit.

!git add gcell.py
!git commit -m "added gcell.py"
!git status
On branch myBranch
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	__pycache__/

nothing added to commit but untracked files present (use "git add" to track)
On branch myBranch
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	__pycache__/

nothing added to commit but untracked files present (use "git add" to track)
!git show
commit ada6e011b864c93c202a176b18ab3b01db8f4801 (HEAD -> myBranch, main)
Author: Kenji Doya <doya@oist.jp>
Date:   Mon Dec 16 14:54:00 2024 +0900

    added gcell.py

diff --git a/gcell.py b/gcell.py
new file mode 100644
index 0000000..cd7b2a5
--- /dev/null
+++ b/gcell.py
@@ -0,0 +1,25 @@
+"""Classes for cells"""
+
+import numpy as np
+import matplotlib.pyplot as plt
+import cell
+
+class gCell(cell.Cell):
+    """Class of growing cell based on Cell class"""
+    
+    def grow(self, scale=2):
+        """Grow the area of the cell"""
+        self.radius *= np.sqrt(scale)
+        
+    def duplicate(self):
+        """Make a copy with a random shift"""
+        c = gCell(self.position+np.random.randn(2)*self.radius, self.radius, self.color)
+        return c
+
+if __name__ == "__main__":
+    c0 = gCell()
+    c0.show()
+    c1 = c0.duplicate()
+    c1.grow()
+    c1.show()
+    plt.show()
!git log --all --graph
* commit ada6e011b864c93c202a176b18ab3b01db8f4801 (HEAD -> myBranch, main)
| Author: Kenji Doya <doya@oist.jp>
| Date:   Mon Dec 16 14:54:00 2024 +0900
| 
|     added gcell.py
| 
* commit fba656aec31be16236f9de2b429e91fac5ef7b2a
  Author: Kenji Doya <doya@oist.jp>
  Date:   Mon Dec 16 14:53:57 2024 +0900
  
      initial version

You can go back to a previous branch by checkout.

!git checkout main
!git log --all --graph
Switched to branch 'main'
* commit ada6e011b864c93c202a176b18ab3b01db8f4801 (HEAD -> main, myBranch)
| Author: Kenji Doya <doya@oist.jp>
| Date:   Mon Dec 16 14:54:00 2024 +0900
| 
|     added gcell.py
| 
* commit fba656aec31be16236f9de2b429e91fac5ef7b2a
  Author: Kenji Doya <doya@oist.jp>
  Date:   Mon Dec 16 14:53:57 2024 +0900
  
      initial version
%ls
__pycache__/ cell.py      gcell.py
!git branch
* main
  myBranch

You can merge another branche to the current branch by git merge

!git merge myBranch
!git log --all --graph
Already up to date.
* commit ada6e011b864c93c202a176b18ab3b01db8f4801 (HEAD -> main, myBranch)
| Author: Kenji Doya <doya@oist.jp>
| Date:   Mon Dec 16 14:54:00 2024 +0900
| 
|     added gcell.py
| 
* commit fba656aec31be16236f9de2b429e91fac5ef7b2a
  Author: Kenji Doya <doya@oist.jp>
  Date:   Mon Dec 16 14:53:57 2024 +0900
  
      initial version