6. Patterns in git and bash#

We will continue working in the gh-inclass repo

cd gh-inclass-brownsarahm/

We added a bunch of files so that we can orgaize them.

ls
API.md			abstract_base_class.py	setup.py
CONTRIBUTING.md		alternative_classes.py	tests_alt.py
LICENSE.md		example.md		tests_helpers.py
README.md		helper_functions.py	tests_imp.py
_config.yml		important_classes.py	tsets_abc.py
_toc.yml		philosophy.md
about.md		scratch.ipynb

We left off on a dedicated branch with a clean working tree.

git status
On branch organization
nothing to commit, working tree clean
pwd
/Users/brownsarahm/Documents/inclass/systems/gh-inclass-brownsarahm
ls
API.md			abstract_base_class.py	setup.py
CONTRIBUTING.md		alternative_classes.py	tests_alt.py
LICENSE.md		example.md		tests_helpers.py
README.md		helper_functions.py	tests_imp.py
_config.yml		important_classes.py	tsets_abc.py
_toc.yml		philosophy.md
about.md		scratch.ipynb

We put an overview in the README:

cat README.md 
# GitHub Practice

Name: Sarah Brown
its finally fall
|file | contents |
> | --| -- |
> | abstract_base_class.py | core abstract classes for the project |
> | helper_functions.py | utitly funtions that are called by many classes |
> | important_classes.py | classes that inherit from the abc |
> | alternative_classes.py | classes that inherit from the abc |
> | LICENSE.md | the info on how the code can be reused|
> | CONTRIBUTING.md | instructions for how people can contribute to the project|
> | setup.py | file with function with instructions for pip |
> | test_abc.py | tests for constructors and methods in abstract_base_class.py|
> | tests_helpers.py | tests for constructors and methods in helper_functions.py|
> | tests_imp.py | tests for constructors and methods in important_classes.py|
> | tests_alt.py | tests for constructors and methods in alternative_classes.py|
> | API.md | jupyterbook file to generate api documentation |
> | _config.yml | jupyterbook config for documentation |
> | _toc.yml | jupyter book toc file for documentation |
> | philosophy.md | overview of how the code is organized for docs |
> | example.md | myst notebook example of using the code |
> | scratch.ipynb | jupyter notebook from dev |

6.1. Making a folder#

First, we’ll make a directory with mkdir

mkdir docs

next we will move a file there with mv

mv philosophy.md docs/

move takes 2 inputs: a source and destination.

we can see what happened

ls
API.md			abstract_base_class.py	setup.py
CONTRIBUTING.md		alternative_classes.py	tests_alt.py
LICENSE.md		docs			tests_helpers.py
README.md		example.md		tests_imp.py
_config.yml		helper_functions.py	tsets_abc.py
_toc.yml		important_classes.py
about.md		scratch.ipynb
ls docs/
philosophy.md

what this does is change the path of the file from .../github-inclass-brownsarahm/philosophy.md to .../github-inclass-brownsarahm/docs/philosophy.md

git does not quite understand though

git status
On branch organization
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:    philosophy.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	docs/

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

it sees a missing file (thinks it is deleted) and a new folder

if we stage the folder, it will start tracking it

git add docs/
git status
On branch organization
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   docs/philosophy.md

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:    philosophy.md

now it sees a new file and a deleted one

if we add everything

git add .
git status
On branch organization
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	renamed:    philosophy.md -> docs/philosophy.md

now it can tell we renamed

6.2. Undoing a change, only in git#

let’s first make change to the README

echo " ">>README.md 
git status
On branch organization
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	renamed:    philosophy.md -> docs/philosophy.md

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   README.md

we can add the readme too

git add .
git status
On branch organization
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   README.md
	renamed:    philosophy.md -> docs/philosophy.md

If we decide to not put these two changes in the same commit, we can unstage the file without losing our changes with restore and its --staged option

git restore --staged README.md 
git status
On branch organization
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	renamed:    philosophy.md -> docs/philosophy.md

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   README.md

Now only the philosophy change will be commited

Now we make that commit

git commit -m 'start organizing (move philosophy)'
[organization 9120d9d] start organizing (move philosophy)
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename philosophy.md => docs/philosophy.md (100%)

Now we can see what git knows

git status
On branch organization
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   README.md

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

and we will commit the README changes

git commi -a -m 'fill in description more (README)'
git: 'commi' is not a git command. See 'git --help'.

The most similar commands are
	commit
	column
	config

first I made a typo, but again, git tries to help

git commit -a -m 'fill in description more (README)'
[organization 4ceb150] fill in description more (README)
 1 file changed, 1 insertion(+)

now we have a clean working tree

git status
On branch organization
nothing to commit, working tree clean

6.3. Undoing a commit#

We will start by looking at our commit history

git log
commit 4ceb1500582236e98bdb141116821a5857f75a76 (HEAD -> organization)
Author: Sarah M Brown <brownsarahm@uri.edu>
Date:   Tue Sep 24 12:44:39 2024 -0400

    fill in description more (README)

commit 9120d9d88aa587e4ffda1ee9aa8c3dcf8f764f7e
Author: Sarah M Brown <brownsarahm@uri.edu>
Date:   Tue Sep 24 12:44:06 2024 -0400

    start organizing (move philosophy)

commit f17e276f43e36a92dd6062cb9e2dae938870c38b
Author: Sarah M Brown <brownsarahm@uri.edu>
Date:   Thu Sep 19 13:42:19 2024 -0400

    explain files

commit 72b85c7834afb148e1298c153a7bad423e995ce0
Author: Sarah M Brown <brownsarahm@uri.edu>
Date:   Thu Sep 19 13:33:44 2024 -0400

    add a note

commit 991ee65fa0d0692bd097915daec156aa95eba82f (origin/main, origin/HEAD, main)

Important

this opens a program so we press q to exit.

recall from the output above, that commit 9120d9 above was like:

[organization 9120d9d] start organizing (move philosophy)
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename philosophy.md => docs/philosophy.md (100%)

it moved philosophy.md to docs/philosophy.md and

Now let’s undo the organizing one, but keep the reame one my hash begins with 9120d9 so I pass that to git revert but you will pass a different hash

git revert 9120d9

git revert requires a message so vimwill open use esc to be sure you are in command mode then type :wq and press enter/return to exit vim

[organization a3904a0] Revert "start organizing (move philosophy)"
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename docs/philosophy.md => philosophy.md (100%)

note that this is a new commit, here hash a3904a0and it does the **opposite** of the  one we reverted9120d9, so it moves docs/philosphy.mdtophilosophy.md`

ls 
API.md			abstract_base_class.py	setup.py
CONTRIBUTING.md		alternative_classes.py	tests_alt.py
LICENSE.md		example.md		tests_helpers.py
README.md		helper_functions.py	tests_imp.py
_config.yml		important_classes.py	tsets_abc.py
_toc.yml		philosophy.md
about.md		scratch.ipynb

With the commit history we can see more clearly that it adds a new commit that is the opposite.

git log
commit a3904a0a5e7adbcbf9fe439c387fb4dbd7846c51 (HEAD -> organization)
Author: Sarah M Brown <brownsarahm@uri.edu>
Date:   Tue Sep 24 12:46:19 2024 -0400

    Revert "start organizing (move philosophy)"
    
    This reverts commit 9120d9d88aa587e4ffda1ee9aa8c3dcf8f764f7e.

commit 4ceb1500582236e98bdb141116821a5857f75a76
Author: Sarah M Brown <brownsarahm@uri.edu>
Date:   Tue Sep 24 12:44:39 2024 -0400

    fill in description more (README)

commit 9120d9d88aa587e4ffda1ee9aa8c3dcf8f764f7e
Author: Sarah M Brown <brownsarahm@uri.edu>
Date:   Tue Sep 24 12:44:06 2024 -0400

    start organizing (move philosophy)

commit f17e276f43e36a92dd6062cb9e2dae938870c38b
Author: Sarah M Brown <brownsarahm@uri.edu>
Date:   Thu Sep 19 13:42:19 2024 -0400

    explain files

6.4. More moving files#

ls
API.md			abstract_base_class.py	setup.py
CONTRIBUTING.md		alternative_classes.py	tests_alt.py
LICENSE.md		example.md		tests_helpers.py
README.md		helper_functions.py	tests_imp.py
_config.yml		important_classes.py	tsets_abc.py
_toc.yml		philosophy.md
about.md		scratch.ipynb

we do actually want that folder so we make it again

mkdir docs

and move the file there

mv philosophy.md docs/

we can move more files more than one at a time by listing multiple paths it moves all but the last one to the last one, which must be a directory, not a file.

mv about.md API.md example.md docs/

we can see that it works

ls
CONTRIBUTING.md		alternative_classes.py	tests_alt.py
LICENSE.md		docs			tests_helpers.py
README.md		helper_functions.py	tests_imp.py
_config.yml		important_classes.py	tsets_abc.py
_toc.yml		scratch.ipynb
abstract_base_class.py	setup.py

6.5. Moving with patterns#

We can use the * wildcard operator to move all files that match the pattern. We’ll start with the two yml (yaml) files that are both for the documentation.

mv *.yml docs/

again we use ls to see it

ls
CONTRIBUTING.md		docs			tests_alt.py
LICENSE.md		helper_functions.py	tests_helpers.py
README.md		important_classes.py	tests_imp.py
abstract_base_class.py	scratch.ipynb		tsets_abc.py
alternative_classes.py	setup.py

and in the folder:

ls docs/
API.md		_toc.yml	example.md
_config.yml	about.md	philosophy.md

6.6. Move is also rename#

We see that most of the test files start with tests_ but one starts with tsets_. We can fix this!

We can use mv to change the name as well. This is because “moving” a file and is really about changing its path, not actually copying it from one location to another and the file name is a part of the path.

mv tsets_abc.py tests_abc.py

This changes the path from .../tsets_abc.py to .../tests_abc.py to. It is doing the same thing as when we use it to move a file from one folder to another folder, but changing a different part of the path.

Next we make a folder for them

mkdir tests

and move all of the test files there:

If we press tab multiple times it shows us what matches the pattern

mv tests
tests/            tests_alt.py      tests_imp.py      
tests_abc.py      tests_helpers.py  

the folder is in there, so if we were to do mv tests* tests/ it would give us an error because the folder also matches tests*

If we add the _

mv tests_

now it’s only what we want to move:

tests_abc.py      tests_alt.py      tests_helpers.py  tests_imp.py

so we run this

mv tests_* tests/
ls
CONTRIBUTING.md		alternative_classes.py	scratch.ipynb
LICENSE.md		docs			setup.py
README.md		helper_functions.py	tests
abstract_base_class.py	important_classes.py
ls tests/
tests_abc.py		tests_helpers.py
tests_alt.py		tests_imp.py

Finally, we wil move the rest of they python files

mkdir src
mv *_*.py
mv: important_classes.py is not a directory

without the target specified it tried to treat the last one as the destination and it did not work

mv *_*.py src/

ls
CONTRIBUTING.md	README.md	scratch.ipynb	src
LICENSE.md	docs		setup.py	tests

6.7. Hidden files and Ignoring files#

We are going to make a special hidden file and an extra one. We will use the following command:

touch .secret .gitignore

We also learn 2 things about touch and bash:

  • touch can make multiple files at a time

  • lists in bash are separated by spaces and do not require brackets

These files will not show by default

ls
CONTRIBUTING.md	README.md	scratch.ipynb	src
LICENSE.md	docs		setup.py	tests

but do with thw -a option

ls -a
.		.github		CONTRIBUTING.md	docs		src
..		.gitignore	LICENSE.md	scratch.ipynb	tests
.git		.secret		README.md	setup.py

gitignore lets us not track certain files

nano .gitignore 

we will ignore the secret file and all notebook files

.secrete
*.ipynb
git status
On branch organization
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:    API.md
	deleted:    _config.yml
	deleted:    _toc.yml
	deleted:    about.md
	deleted:    abstract_base_class.py
	deleted:    alternative_classes.py
	deleted:    example.md
	deleted:    helper_functions.py
	deleted:    important_classes.py
	deleted:    philosophy.md
	deleted:    tests_alt.py
	deleted:    tests_helpers.py
	deleted:    tests_imp.py
	deleted:    tsets_abc.py

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	.gitignore
	docs/
	src/
	tests/

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

again we will add all so that git can see we moved files

git add .
git status
On branch organization
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   .gitignore
	renamed:    API.md -> docs/API.md
	renamed:    _config.yml -> docs/_config.yml
	renamed:    _toc.yml -> docs/_toc.yml
	renamed:    about.md -> docs/about.md
	renamed:    example.md -> docs/example.md
	renamed:    philosophy.md -> docs/philosophy.md
	renamed:    abstract_base_class.py -> src/abstract_base_class.py
	renamed:    alternative_classes.py -> src/alternative_classes.py
	renamed:    helper_functions.py -> src/helper_functions.py
	renamed:    important_classes.py -> src/important_classes.py
	renamed:    tsets_abc.py -> tests/tests_abc.py
	renamed:    tests_alt.py -> tests/tests_alt.py
	renamed:    tests_helpers.py -> tests/tests_helpers.py
	renamed:    tests_imp.py -> tests/tests_imp.py

better !

and note that the .secret file is not in the list, git is ignoring it.

we will make a commit now

git commit -m 'organized files into foleders and ignore private'
[organization d2d1fac] organized files into foleders and ignore private
 15 files changed, 2 insertions(+)
 create mode 100644 .gitignore
 rename API.md => docs/API.md (100%)
 rename _config.yml => docs/_config.yml (100%)
 rename _toc.yml => docs/_toc.yml (100%)
 rename about.md => docs/about.md (100%)
 rename example.md => docs/example.md (100%)
 rename philosophy.md => docs/philosophy.md (100%)
 rename abstract_base_class.py => src/abstract_base_class.py (100%)
 rename alternative_classes.py => src/alternative_classes.py (100%)
 rename helper_functions.py => src/helper_functions.py (100%)
 rename important_classes.py => src/important_classes.py (100%)
 rename tsets_abc.py => tests/tests_abc.py (100%)
 rename tests_alt.py => tests/tests_alt.py (100%)
 rename tests_helpers.py => tests/tests_helpers.py (100%)
 rename tests_imp.py => tests/tests_imp.py (100%)
git status
On branch organization
nothing to commit, working tree clean

we can check the files too

ls -a
.		.github		CONTRIBUTING.md	docs		src
..		.gitignore	LICENSE.md	scratch.ipynb	tests
.git		.secret		README.md	setup.py

we still have the file but git does nto see it

we can confirm by pushing

git push 
fatal: The current branch organization has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin organization

To have this happen automatically for branches without a tracking
upstream, see 'push.autoSetupRemote' in 'git help config'.

but we have to pair this branch to a remote

git push --set-upstream origin organization
Enumerating objects: 22, done.
Counting objects: 100% (22/22), done.
Delta compression using up to 8 threads
Compressing objects: 100% (18/18), done.
Writing objects: 100% (20/20), 2.55 KiB | 2.55 MiB/s, done.
Total 20 (delta 8), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (8/8), completed with 1 local object.
remote: 
remote: Create a pull request for 'organization' on GitHub by visiting:
remote:      https://github.com/compsys-progtools/gh-inclass-brownsarahm/pull/new/organization
remote: 
To https://github.com/compsys-progtools/gh-inclass-brownsarahm.git
 * [new branch]      organization -> organization
branch 'organization' set up to track 'origin/organization'.

in our browser we notice the file is not there, but the .ipynb file still is

let’s try editing it

nano scratch.ipynb 

and checkign with git

git status
On branch organization
Your branch is up to date with 'origin/organization'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   scratch.ipynb

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

it is still tracking, because .gitignore does not remove files from tracking it only prevents tracking from starting

we can learn about git commands with --help

git rm --help

it is a program we exit with q

we want to remove it from git, but not delete it locally, so we use --cached option on git rm

git rm --cached scratch.ipynb 
rm 'scratch.ipynb'

we can still see it

ls
CONTRIBUTING.md	README.md	scratch.ipynb	src
LICENSE.md	docs		setup.py	tests
git status
On branch organization
Your branch is up to date with 'origin/organization'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	deleted:    scratch.ipynb

git thinks it is deleted

so we commit this

git commit -m 'stop tracking'
[organization 87c72ae] stop tracking
 1 file changed, 1 deletion(-)
 delete mode 100644 scratch.ipynb

now we can edit it more

echo "a change" >> scratch.ipynb 

and check git

git status
On branch organization
Your branch is ahead of 'origin/organization' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

it dose not see!

echo "again change" >> scratch.ipynb 
git status
On branch organization
Your branch is ahead of 'origin/organization' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

doesn’t see it!

git push
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 229 bytes | 229.00 KiB/s, done.
Total 2 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/compsys-progtools/gh-inclass-brownsarahm.git
   d2d1fac..87c72ae  organization -> organization

and we note that it is now removed online.

6.8. Copying a file#

cp copies

cp README.md docs/overview.md
git status
On branch organization
Your branch is up to date with 'origin/organization'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	docs/overview.md

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

git commit -m 'include readmen content'
[organization 1e2ab92] include readmen content
 1 file changed, 24 insertions(+)
 create mode 100644 docs/overview.md

We discussed the solution to the prepare,

  • edith .templates/experience-refletion for your name

  • add reviwers:VioletVex at the end of .github/workflows/experienceinclass.yml

6.9. Prepare for Next Class#

  1. Think through and make some notes about what you have learned about design so far. Try to answer the questions below in design_before.md. If you do not now know how to answer any of the questions, write in what questions you have.

- What past experiences with making decisions about design of software do you have?
- what experiences studying design do you have? 
- What processes, decisions, and practices come to mind when you think about designing software?
- From your experiences as a user, how you would describe the design of command line tools vs other GUI based tools?

6.10. Badges#

  1. lab Organize the provided messy folder in a Codepsace (details will be provided in lab time). Commit and push the changes. Answer the questions below in your kwl (this) repo in a file called terminal_organization.md

  2. clone your messy_repo locally and append the history.md file to your terminal_organization.md using a redirect

# Terminal File moving reflection

1. How was this activity overall?
1. Did this get easier toward the end?
4. When do you think that using the terminal will be better than using your GUI file explorer?
5. What questions/challenges/ reflections do you have after this?

badge steps marked lab are steps that you will be encouraged to use lab time to work on. For this one in particular, I am going to give you the messy repo in lab.

  1. lab Organize the provided messy folder (details will be provided in lab time). Commit and push the changes. Clone that repo locally.

  2. Organize a folder on your computer ( good candidate may be desktop or downloads folder), using only a terminal to make new directories, move files, check what’s inside them, etc. Answer reflection questions in a new file, terminal_organization_adv.md in your kwl repo. Tip: Start with a file explorer open, but then try to close it, and use only command line tools to explore and make your choices. If you get stuck, look up additional commands to do acomplish your goals.

# Terminal File moving reflection
1. How was this activity overall?
1. Did this get easier toward the end?
2. How was it different working on your own computer compared to the Codespace form? 
3. Did you have to look up how to do anything we had not done in class?
4. When do you think that using the terminal will be better than using your GUI file explorer?
5. What questions/challenges/ reflections do you have after this?
6. Append all of the commands you used in lab below. (not from your local computer's history, from the codespace history)

6.11. Experience Report Evidence#

append your gh inclass git log and history from the abovce to a file evidence-2024-09-24.md on the branch in your fall24- repo

6.12. Questions After Today’s Class#

6.12.1. What are some other useful git bash commands to ensure safety in removing, ignoring, moving, renaming, and making?#

We have covered a lot of the most commonly used ones at this point. We will learn some more, but also looking up different people’s bash or git cheatsheets is a good contribution to the site for a community badge. Comparing them extensively could be an explore badge

6.12.2. What are other special files in git?#

Next week we will dig into how git works under the hood and that will see more

6.12.3. is .gitignore something standard from github or just a git bash thing?#

it is standard to git no matter what host (github, bitbucket, gitlab) or terminal (mac termnial, gitbash, anaconda prompt) or shell (bash, zsh, powershell) you use.

6.12.4. How do I combine pull requests#

Pull requests compare two branches.

For example you might have

gitGraph commit id:"D" commit id:"E" branch prepare branch experience checkout prepare commit id:"do prepare work" checkout experience commit id:"init experience badge"

and have one PR from prepare to main and another from experience to main. If you change the base of the prepare one to be expereince and then merge it, then you have:

gitGraph commit id:"D" commit id:"E" branch prepare branch experience checkout prepare commit id:"do prepare work" checkout experience commit id:"init experience badge" merge prepare

and everything will show in the experience PR