==================================== Git ==================================== Git is a free and open source `distributed` version control system (`VCS`__) to efficiently handle small and big projects (such as developing codes). It differes with `client-server` systems where there is only one computer that contains a "master repository" that keeps the history of changes made. In a distributed system, such as Git, any working copy of the master repository contains the full history of changes. Importantly, Git allows groups of people to work on the same documents (often codes) at the same time without interfering with eachother. This section goes through the most basic parts of git. More in-depth tutorials and information can be found on the official `Git webpage`__. Installing Git +++++++++++++++++++++++++++++ Before you start using Git, you have to make it available on your computer. Even if it is already installed, it may be a good idea to update to the last version. To see which version of git you have, in your terminal you can type .. code-block:: none $ git --version git version 2.11.0 (Apple Git-81) This means I have version 2.11.0. If you get something like ``-bash: git: command not found``, then it means either Git is not installed or it is not on PATH. To find the path and to make sure that git is installed type .. code-block:: none $ which git /usr/bin/git If git is installed, and if it is not on PATH (See `this`__), then you will need to add the path that you find (i.e. `/usr/bin/git`) to PATH in your `.profile` file: .. code-block:: none $ echo 'export PATH=/usr/bin:$PATH' >> ~/.profile If Git is not installed, then `install Git`__. Cloning your Bitbucket repository ++++++++++++++++++++++++++++++++++++++++++++++ Let us now clone the repository that you created on `Bitbucket`__, that is, make a copy of your Bitbucket repository on your computer: 1) On your computer, move to the directory where you want your copy of the repository to reside. 2) Clone the respoitory by typing (you will need to use your own Bitbucket username and repository name): .. code-block:: none $ git clone https://motamed@bitbucket.org/motamed/hpsc2020.git Cloning into 'hpsc2020'... warning: You appear to have cloned an empty repository. This will download the entire repository (i.e. hpsc2020) as a new subdirectory with the same name (i.e. hpsc2020). 3) **Excersice:** Try to define and set a UNIX environment variable to refer to the directory you have just created. See `this`__ and `that`__. Git commands (fetch, merge, pull, status, add, commit, log, push) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1) Now move to the new created directory and type ``$ ls``: .. code-block:: none $ cd hpsc2020 $ ls $ This will not generate any response, because for the moment this subdirectory is empty, as there is no file or subdirectory in your Bitbucket repository. What if you type ``$ ls -a``? .. code-block:: none $ ls -a . .. .git The ``-a`` option makes ``ls`` display the hidden files and directories (those started with a dot). One of the hidden directories is "`.git`", which is used by Git to store the information and history of every file and every change ever committed to this directory. You should not modify this directory. 2) The files in the repository will change over time (you will add and modify files and sub-directories). In order to bring all changes over to your cloned copy, you will need to do: .. code-block:: none $ git fetch origin $ git merge origin/master This will fetch any changes from ``origin`` (i.e. the remote Bitbucket repository that you originally cloned from) and merge them to your ``master`` branch (i.e the main branch in your local repository). The last two command can be combined as: .. code-block:: none $ git pull origin master or simply: .. code-block:: none $ git pull since origin and master are the defaults. This would display the following response: .. code-block:: none Already up-to-date. Since we have not added/changed anything, Git tells us we are already up-to-date. 3) Add a new file to your directory, say "`test.txt`", containing the following two lines (or something like this): .. code-block:: none This is a test file. It is a text containing only two lines. 4) Now let us look at the status: .. code-block:: none $ git status On branch master Initial commit Untracked files: (use "git add ..." to include in what will be committed) test.txt nothing added to commit but untracked files present (use "git add" to track) This message tells me that I am on the "master branch" and that I have made an initial commit to an untracked file "`text.txt`". Alternatively, we can check the status by adding the ``-s`` flag to get a `short` status list: .. code-block:: none $ git status -s ?? test.text The ?? sign means that this file is not under revision control. 5) We will first need to include the changes (here the whole new file) in what will be comitted and then commit the changes, that is, we need to put the file under revision control: .. code-block:: none $ git add test.txt Now take a look at the status again: .. code-block:: none $ git status On branch master Initial commit Changes to be committed: (use "git rm --cached ..." to unstage) new file: test.txt Or alternatively: .. code-block:: none $ git status -s A test.txt The A means the file `test.txt` has been added and is now under revision control. 6) At this point we can enter some information about this version of the file: .. code-block:: none $ git commit -m "My 1st commit of test.txt." [master (root-commit) 41ff0ad] My 1st commit of test.txt. 1 file changed, 2 insertions(+) create mode 100644 test.txt The string following the ``-m`` flag is an informative message about this commit that may help you remember why you committed new or changed files. Now check the status: .. code-block:: none $ git status On branch master nothing to commit, working tree clean Note that if you would like to check the status of a single file, you can type: .. code-block:: none $ git status test.txt 7) We can get a list of all commits that we have made (only one so far): .. code-block:: none $ git log commit 41ff0aded92f3b846dc5683729b7912c5134b702 Author: motamed Date: Fri Aug 14 14:42:48 2020 -0600 My 1st commit of test.txt. The 40 digit number ``41ff0aded92f3b846dc5683729b7912c5134b702`` is the "name" of the commit we made. It is a "hexa-decimal number" in base 16: in addition to 0, 1, ..., 9, there are 6 more digits a, b, c, d, e, f representing 10 through 15. This number, which is unique among all commits you will ever do, allows you to get back to older versions/states of your file. See `SHA-1`__ if you like to learn more on this. 8) If you are happy with the commit you just did, you can push it to the remote Bitbucket repository as follows. First do: .. code-block:: none $ git status -s to make sure there are no uncommitted changes. This should print nothing. Next do: .. code-block:: none $ git push -u origin master Counting objects: 3, done. Delta compression using up to 4 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 270 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To https://bitbucket.org/motamed/hpsc2017.git * [new branch] master -> master Branch master set up to track remote branch master from origin. The ``push`` command may also prompt for your Bitbucket password. It copies the file together with the entire history of your commits in the repository. So, if someone else clones the Bitbucket repository, they get the entire commit history and could revert to any previous version. To push future commits to Bitbucket, you would only need to do: .. code-block:: none $ git push This would push your master branch (the only branch you currently have) to origin, which refer to the place from where you originally cloned the repository. 9) Finally check that the file is in your Bitbucket repository. For this, go back to the web page for your repository and click on the "Source" tab. It should display the files in your repository. Also click on the "Commits" tab to see the commits you made together with the comments. **Remark:** Notice that you can do multiple local commits before you push. A few tips +++++++++++++++++++++++ In case you work on your Git repository on more than one machine, the following tips will help you stay synced up on multiple computers and avoid having conflicts or missing things: * When you start working on a computer, make sure you are up to date (using ``git pull`` or using both ``git fetch`` and ``git merge``). * When you finish working on a computer, make sure your directory is "clean" (using ``git status``). If not, ``git add`` and ``git commit`` the changes. * Make sure all commits are pushed to Bitbucket (using ``git push``). __ http://math.unm.edu/~motamed/Teaching/Fall20/HPSC/vc.html __ https://git-scm.com/ __ https://math.unm.edu/~motamed/Teaching/Fall20/HPSC/unix.html#the-bashrc-or-profile-files __ https://git-scm.com/ __ http://math.unm.edu/~motamed/Teaching/Fall20/HPSC/bitbucket.html#creating-your-own-bitbucket-repository __ http://math.unm.edu/~motamed/Teaching/Fall20/HPSC/unix.html#environment-variables __ http://math.unm.edu/~motamed/Teaching/Fall20/HPSC/unix.html#the-bashrc-or-profile-files __ https://en.wikipedia.org/wiki/SHA-1