Git

To date a goodly number of the exercises involve a gradual improvement of code and/or modifications to add function. I have been using file names like ???_v1.py, ???_v2.py, etc to maintain the versions. Not likely the best approach.

Likely better to use a solid “version control system” than an ad hoc series of versioned file names. A versioning system would allow me to track the changes and not create a new file unless there was a good reason. For example, going from procedural code to class based code. Or adding seriously new functionality (which would likely be a good case for a ‘branch’, rather than just a file version).

I know I am primarily dealing with single files rather than a significant coding project. So, my past approach is probably just fine. But, I’m doing this to learn. So, start small, learn and grow. Hopefully I will develop the habit of using it for my learning projects.

And, yes, I am going to install it in my ‘appDev’ folder in the Dev partition (e:\appDev\Git).

So download the appropriate bit version of the installer from https://git-scm.com/download/win. Version 2.25.1 at this moment. Start the installer. Choose “Install anyway” to bypass the MS app store warning. Tell the user account control pop-up that it’s okay to go ahead. Read the info presented and when ready, click “Next >”.

Accept the installation location or change it to suit your preferences. I did the latter.

I went with the default components. I let it create a Start menu folder, though not certain that is really necessary. I chose to “Use the Nano editor by default.” Can always change this in the config later. I went with the default in the next window, “Git from the command line and also from 3rd-party software.” VS Code can work with Git. And again the default, “Use the OpenSSL library.” I went with the default for configuring the line ending conversions. I.E. “Checkout Windows-style, commit Unix-style line endings. I decided to change the default in the next step and went with “Use Windows’ default console window” - for better or worse. Lots of setup steps. Went with the default for Configuring extra options. Then hit “Install.” And, being a bit lazy at the moment I skipped reading the release notes.

And I will pause here for now, time to start on prepping supper (slice, dice and such).

Create a GitHub Account

Go to the GitHub pricing page (https://github.com/pricing). In the box for the Free plan, click Join for free. Enter the requested information, paying particular attention to the requirements for the password. I was not asked to enter the password a 2nd time for confirmation? Click ‘Select a Plan’. Click ‘Choose Free’.

On the welcome page I selected: Student (well I am for all present purposes), A little, Learn to code. Then typed in python (then I hit a wrong key, never got to enter ‘data science’). The wrong key took me to the verify your email address page. I opened the verification email in my e-mail client, copied the link and pasted it into the browser. On hitting enter, I got a 404 page, but there was a message indicating my email was verified and I was logged into GitHub. It asked if I wanted to create my first repository.

So I clicked the ‘+’ at the right of the header bar (black bar) and selected ‘New repository’.

  • Repository name: pyPlay
  • Description: My first repository. For some python environment setup and testing.
  • Public or Private: I selected Private. No need to clutter the public internet with the junk I expect to be putting into this repository.
  • I selected ‘Initialize this repository with a README’.
  • Add .gitignore: None
  • Add a license: GNU General Public License v3.0
  • And finally clicked ‘Create repository’.

When asked about GitHub Actions I clicked ‘Dismiss’. Don’t yet know enough to go tackle that. And there you go, your first commit to GitHub. Now to figure out how to get that repository into our ‘install’ folder without deleting what we already have in there (.vscode, test .py file, etc).

For the moment let’s leave the web site. I haven’t bothered to log out just yet.

Fetch New Repository into Our Play Folder

Okay, I renamed the install folder to py_play to keep it consistent with the new repository on GitHub. And, I deleted the test_conda_python.py file. We will write a slightly more interesting bit of code once we have our initial workspace set up and committed to GitHub.

Open a command window and move to the py_play directory.

C:\Users\bark>cd /D r:\learn\py_play

Create an empty Git repository in the the py_play folder.

r:\learn\py_play>git init
Initialized empty Git repository in R:/learn/py_play/.git/

To save ourselves the need to always enter the GitHub repository link for all future Git commands, we will add a remote link to the GitHub repository in the local Git configuration. You will need to use the appropriate link for your GitHub repository.

r:\learn\py_play>git remote add origin https://github.com/tooOld2Code/pyPlay.git

Now let’s fetch our GitHub repository into new, empty local Git repository. You may have heard of the git clone command, but it will not work as we already have a local respository in our folder. We will instead use git fetch. (Yes I had to duckduckgo the solution. Along with a few others below.) Enter your username and password when asked for them. Note, nothing is displayed when you enter the password, so be careful.

r:\learn\py_play>git fetch
Username for 'https://github.com': tooOld2Code
Password for 'https://tooOld2Code@github.com':
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (4/4), 12.51 KiB | 23.00 KiB/s, done.
From https://github.com/tooOld2Code/pyPlay
 * [new branch]      master     -> origin/master

Now we need to join (sure that’s the wrong term, but…) the git history from the GitHub repository to our local Git respository.

r:\learn\py_play>git reset --mixed origin/master
Unstaged changes after reset:
D       LICENSE
D       README.md

Let’s have a look at how things stand.

r:\learn\py_play>git status
On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        deleted:    LICENSE
        deleted:    README.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .vscode/
        pyPlay.code-workspace

no changes added to commit (use "git add" and/or "git commit -a")

Well, our license and readme are apparently deleted. We don’t want that. It’s part of the git fetch thing I believe. So let’s restore them. Actually let’s first list the contents of the directory, then restore the 2 files.

r:\learn\py_play>dir
 Volume in drive R is Dev2
 Volume Serial Number is 6E89-FF7A

 Directory of r:\learn\py_play

2020-03-14  15:45    <DIR>          .
2020-03-14  15:45    <DIR>          ..
2020-03-14  15:14    <DIR>          .vscode
2020-03-14  15:16                62 pyPlay.code-workspace
               1 File(s)         62 bytes
               3 Dir(s)  98,047,225,856 bytes free


r:\learn\py_play>git restore LICENSE

r:\learn\py_play>git restore README.md

And, again check the git status.

r:\learn\py_play>git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .vscode/
        pyPlay.code-workspace

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

No deleted files. So let’s list the folder contents again.

r:\learn\py_play>dir
 Volume in drive R is Dev2
 Volume Serial Number is 6E89-FF7A

 Directory of r:\learn\py_play

2020-03-14  15:45    <DIR>          .
2020-03-14  15:45    <DIR>          ..
2020-03-14  15:14    <DIR>          .vscode
2020-03-14  15:45            35,823 LICENSE
2020-03-14  15:16                62 pyPlay.code-workspace
2020-03-14  15:45                79 README.md
               3 File(s)         35,964 bytes
               3 Dir(s)  98,047,225,856 bytes free

You will need to enter the following command exactly as shown. “4b825dc642cb6eb9a060e54bf8d69288fbee4904 is the id of the ’empty tree’ in Git and it’s always available in every repository”. It’s purpose is to show us what changed between the ’empty tree’ and our fist commit. Hitting enter will continue showing info one line at a time. Pressing ‘Page Down’ will show additional info in larger chunks. Entering ‘Q’ will stop the diff display and return to the cmd prompt. When you see something like END you also need to press ‘Q’ to get back to the prompt. I have deleted numerous lines from the display below. This was just for my personal interest. Basically the + at the start of a line indicates it was added since the previous commit (in our case, empty repository before anything was added and committed). Our first commit included the 2 files LICENSE and README.md.

r:\learn\py_play>git diff 4b825dc642cb6eb9a060e54bf8d69288fbee4904 HEAD
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..f288702
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to

--- snip ---

+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<https://www.gnu.org/licenses/why-not-lgpl.html>.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..f26ec8f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+# pyPlay
+My first repository. For some python environment setup and testing.

Create a conda Requirements File

If we want to share our conda environment with a friend or collaborator, the easiest way is to provide them with a conda environment file. This is a listing of all the packages, along with their version numbers, that are installed in your project’s environment. Well I am actually going to create three files, requirements.txt which can be used with pip, conda_requirements.txt and base-3.8.yml for conda. The only one I really want is conda_requirements.txt, but…

Open an Anaaconda Prompt (Miniconda). And move to the py_play (or whatever you called it) directory, and activate the environment

(base) C:\Users\bark>cd /D r:\learn\py_play

(base) r:\learn\py_play>conda activate base-3.8

(base-3.8) r:\learn\py_play>conda env list
# conda environments:
#
base                     E:\appDev\Miniconda3
base-3.8              *  E:\appDev\Miniconda3\envs\base-3.8

Then run the following 3 commands.

(base-3.8) r:\learn\py_play>conda list --explicit > conda_requirements.txt

(base-3.8) r:\learn\py_play>conda env export > base-3.8.yml

(base-3.8) r:\learn\py_play>pip freeze > requirements.txt

Have a look at the three files. You can open in an editor or print in the cmd window (e.g. type requirements.txt).

 (base-3.8) r:\learn\py_play>type conda_requirements.txt
 # This file may be used to create an environment using:
 # $ conda create --name <env> --file <this file>
 # platform: win-64
 @EXPLICIT
 https://repo.anaconda.com/pkgs/main/win-64/blas-1.0-mkl.conda
 https://repo.anaconda.com/pkgs/main/win-64/ca-certificates-2020.1.1-0.conda
 https://repo.anaconda.com/pkgs/main/win-64/icc_rt-2019.0.0-h0cc432a_1.conda
 https://repo.anaconda.com/pkgs/main/win-64/intel-openmp-2020.0-166.conda
 https://repo.anaconda.com/pkgs/main/win-64/vs2015_runtime-14.16.27012-hf0eaf9b_1.conda
 https://repo.anaconda.com/pkgs/main/win-64/mkl-2020.0-166.conda
 https://repo.anaconda.com/pkgs/main/win-64/vc-14.1-h0510ff6_4.conda
 https://repo.anaconda.com/pkgs/main/win-64/icu-58.2-ha66f8fd_1.conda
 https://repo.anaconda.com/pkgs/main/win-64/jpeg-9b-hb83a4c4_2.conda
 https://repo.anaconda.com/pkgs/main/win-64/openssl-1.1.1d-he774522_4.conda
 https://repo.anaconda.com/pkgs/main/win-64/sqlite-3.31.1-he774522_0.conda
 https://repo.anaconda.com/pkgs/main/win-64/zlib-1.2.11-h62dcd97_3.conda
 https://repo.anaconda.com/pkgs/main/win-64/libpng-1.6.37-h2a8f88b_0.conda
 https://repo.anaconda.com/pkgs/main/win-64/python-3.8.1-h5fd99cc_8_cpython.conda
 https://repo.anaconda.com/pkgs/main/win-64/certifi-2019.11.28-py38_0.conda
 https://repo.anaconda.com/pkgs/main/noarch/colorama-0.4.3-py_0.conda
 https://repo.anaconda.com/pkgs/main/win-64/freetype-2.9.1-ha9979f8_1.conda
 https://repo.anaconda.com/pkgs/main/win-64/kiwisolver-1.0.1-py38ha925a31_0.conda
 https://repo.anaconda.com/pkgs/main/win-64/lazy-object-proxy-1.4.3-py38he774522_0.conda
 https://repo.anaconda.com/pkgs/main/win-64/mccabe-0.6.1-py38_1.conda
 https://repo.anaconda.com/pkgs/main/noarch/pyparsing-2.4.6-py_0.conda
 https://repo.anaconda.com/pkgs/main/win-64/qt-5.9.7-vc14h73c81de_0.conda
 https://repo.anaconda.com/pkgs/main/win-64/sip-4.19.13-py38ha925a31_0.conda
 https://repo.anaconda.com/pkgs/main/win-64/six-1.14.0-py38_0.conda
 https://repo.anaconda.com/pkgs/main/win-64/tornado-6.0.3-py38he774522_3.conda
 https://repo.anaconda.com/pkgs/main/win-64/wincertstore-0.2-py38_0.conda
 https://repo.anaconda.com/pkgs/main/win-64/wrapt-1.11.2-py38he774522_0.conda
 https://repo.anaconda.com/pkgs/main/win-64/cycler-0.10.0-py38_0.conda
 https://repo.anaconda.com/pkgs/main/win-64/mkl-service-2.3.0-py38hb782905_0.conda
 https://repo.anaconda.com/pkgs/main/win-64/pyqt-5.9.2-py38ha925a31_4.conda
 https://repo.anaconda.com/pkgs/main/noarch/python-dateutil-2.8.1-py_0.tar.bz2
 https://repo.anaconda.com/pkgs/main/win-64/setuptools-45.2.0-py38_0.conda
 https://repo.anaconda.com/pkgs/main/win-64/astroid-2.3.3-py38_0.conda
 https://repo.anaconda.com/pkgs/main/win-64/isort-4.3.21-py38_0.conda
 https://repo.anaconda.com/pkgs/main/win-64/numpy-base-1.18.1-py38hc3f5095_1.conda
 https://repo.anaconda.com/pkgs/main/win-64/wheel-0.34.2-py38_0.conda
 https://repo.anaconda.com/pkgs/main/win-64/pip-20.0.2-py38_1.conda
 https://repo.anaconda.com/pkgs/main/win-64/pylint-2.4.4-py38_0.conda
 https://repo.anaconda.com/pkgs/main/win-64/matplotlib-3.1.3-py38_0.conda
 https://repo.anaconda.com/pkgs/main/win-64/matplotlib-base-3.1.3-py38h64f37c6_0.conda
 https://repo.anaconda.com/pkgs/main/win-64/mkl_fft-1.0.15-py38h14836fe_0.conda
 https://repo.anaconda.com/pkgs/main/win-64/mkl_random-1.1.0-py38hf9181ef_0.conda
 https://repo.anaconda.com/pkgs/main/win-64/numpy-1.18.1-py38h93ca92e_0.conda

Commit our VS Code project files and Conda Requirements File(s)

Hopefully this will be simple enough. But you should know that there is a general feeling that the VS Code files should not be included in your Git repository. They are pretty much user specific and if included in a clone or fetch could mess up the other person’s VS Code setup. Then again they may not be using VS Code in which case they don’t need the files at all. And, I am only going to include the conda_requirements.txt file in the repository. The others can be generated at need in future.

So, I am going to create a .gitignore file telling git to ignore VS Code stuff (well with some exceptions), and the other 2 requirements files.

Let’s start by checking our Git status.

(base-3.8) r:\learn\py_play>git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .vscode/
        base-3.8.yml
        conda_requirements.txt
        pyPlay.code-workspace
        requirements.txt

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

Now in your editor, create a .gitignore file in the py_play directory and add the following lines:

base-3.8.yml
requirements.txt

### VisualStudioCode ###
*.code-workspace
.vscode/*
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

### VisualStudioCode Patch ###
# Ignore all local history of files
**/.history

Once you’re done, have another look at Git’s status.

(base-3.8) r:\learn\py_play>git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
    .gitignore
    conda_requirements.txt

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

Note that the two files and the VS Code files listed in .gitignore are no longer listed as untracked. Finally let’s commit the remaining files, and push the changes to GitHub.

(base-3.8) r:\learn\py_play>git add .gitignore

(base-3.8) r:\learn\py_play>git add conda_requirements.txt

(base-3.8) r:\learn\py_play>git commit -m "add .gitignore and conda requirements file"
[master 780fc5a] add .gitignore and conda requirements file
 2 files changed, 60 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 conda_requirements.txt

(base-3.8) r:\learn\py_play>git log
commit 780fc5a0cb296a4fbd73e3aadea2f8b591d55dba (HEAD -> master)
Author: koach aka Rick K <barkncats@users.noreply.github.com>
Date:   Sun Mar 15 11:01:55 2020 -0700

    add .gitignore and conda requirements file

commit 0588ec490b928d69972df28494c8517592e1cabb (origin/master)
Author: tooOld2Code <62121320+tooOld2Code@users.noreply.github.com>
Date:   Thu Mar 12 15:52:50 2020 -0700

Initial commit

And, finally, well not quite. I don’t want to have to keep entering my username and password each time I push, pull, etc. So run the following, providing your username and password when requested.

(base-3.8) r:\learn\py_play>git config credential.helper store

(base-3.8) r:\learn\py_play>git push --set-upstream origin master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 16 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 1.30 KiB | 667.00 KiB/s, done.
Total 4 (delta 0), reused 0 (delta 0)
To https://github.com/tooOld2Code/pyPlay.git
   0588ec4..780fc5a  master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

And, there we go. Our project setup has now been committed locally and on GitHub. Log in and have a look.

Second Thoughts

I know this is a rather lengthy post. But I want to add just a bit more.

The whole thing with creating a GitHub repository with a commit (license and readme files), a local empty respository, git fetch, fixing deleted files, etc. was a bit of a mess. In future I would proceed differently, doing one of the following.

If I created the GitHub repository with an initial commit. I would do a git clone into a new empty project folder. Then I would go through the process of creating a VS Code workspace, and adding a virtual environment to that workspace. Create the requirements file, and commit the initial workspace setup.

Or, I would create an empty GitHub repository. Do my thing locally, including adding license and readme files (if needed). Then push the initial project setup to GitHub as a first commit.

I will leave it to you to sort your preferred workflow.

Until the next time. Please note, that I am back to a weekly, Monday, posting schedule for now.

Further Resources

At git-scm.com:

Stack Overflow (these all helped me sort various issues I had):