#

0 syntax#

The basic structure or syntax of a Unix command is made up of several components. Here’s a general breakdown:

  1. Command Name: This is the actual command you want to run, such as ls, grep, awk, etc.

  2. Options: These modify the behavior of the command. Options typically start with a dash (-) and can be either a single letter or a full word preceded by two dashes. For example, -l or --long-option. Options can change the way the command operates, enable or disable features, etc.

  3. Arguments: These are the targets of the command, such as filenames, directories, or other input values. They come after the command and the options.

  4. Redirection and Pipes: You can also use symbols like >, <, >>, |, etc., to redirect input and output or to pipe the output of one command into another.

Here’s a general example:

command -option1 -option2 argument1 argument2 > outputfile
  • command: The name of the command to run.

  • -option1 and -option2: Options that modify how the command behaves.

  • argument1 and argument2: Arguments or operands the command will act upon.

  • > outputfile: Redirects the standard output of the command to a file called outputfile.

It’s worth noting that the specifics can vary quite a bit depending on the command, as different commands can have vastly different options and expected arguments. Always refer to the command’s manual page (accessed by running man command-name) for detailed information on how a particular command should be used.


  • agent user@mac dir $

  • verb command -options

  • object argument

options are modifiers of the verb (adverbs if you will)


The double-dash -- is often used in Unix command-line utilities to signify the end of command options. After --, any following arguments are treated as operands and not as options, even if they start with a dash -.

Here’s an example to illustrate the usage of --. Let’s say you have a file named -file.txt, and you want to remove it using the rm command. If you try to remove it like this:

rm -file.txt

The command-line will interpret -file.txt as an option to the rm command and return an error since there’s no such option.

But if you use --, you can tell the command that you’re done with options, and everything after -- is an operand:

rm -- -file.txt

This command will successfully remove the file named -file.txt.


1 abikesa_jbc5.sh#

```bash

#!/bin/bash

# Check if required commands are available
for cmd in git ssh-keygen jb ghp-import; do
  if ! command -v $cmd &> /dev/null; then
    echo "Error: $cmd is not installed."
    exit 1
  fi
done

# Input information
read -p "Enter your GitHub username: " GITHUB_USERNAME
read -p "Enter your GitHub repository name: " REPO_NAME
read -p "Enter your email address: " EMAIL_ADDRESS
read -p "Enter your root directory (e.g., ~/Dropbox/1f.ἡἔρις,κ/1.ontology): " ROOT_DIR
read -p "Enter the name of the subdirectory to be created within the root directory: " SUBDIR_NAME
read -p "Enter the name of the populate_be.ipynb file in ROOT_DIR: " POPULATE_BE
read -p "Enter your git commit message: " GIT_COMMIT_MESSAGE

# Set up directories and paths
git config --local user.name "$GITHUB_USERNAME"
git config --local user.email "$EMAIL_ADDRESS"
cd $(eval echo $ROOT_DIR)
rm -rf $REPO_NAME
mkdir -p $SUBDIR_NAME
cp $POPULATE_BE $SUBDIR_NAME/intro.ipynb
cd $SUBDIR_NAME

# Check if SSH keys already exist, and if not, generate a new one
SSH_KEY_PATH="$HOME/.ssh/id_${SUBDIR_NAME}${REPO_NAME}"
rm -rf $SSH_KEY_PATH*
if [ ! -f "$SSH_KEY_PATH" ]; then
  ssh-keygen -t ed25519 -C "$EMAIL_ADDRESS" -f $SSH_KEY_PATH
fi

cat ${SSH_KEY_PATH}.pub
echo "Please manually add the above SSH public key to your GitHub account's SSH keys."
read -p "Once you have added the SSH key to your GitHub account, press Enter to continue..."
eval "$(ssh-agent -s)"
ssh-add --apple-use-keychain $SSH_KEY_PATH

# Number of acts, files per act, and sub-files per file
NUMBER_OF_ACTS=9
NUMBER_OF_FILES_PER_ACT=9
NUMBER_OF_SUB_FILES_PER_FILE=2
NUMBER_OF_NOTEBOOKS=3

# Create _toc.yml file
toc_file="_toc.yml"
echo "format: jb-book" > $toc_file
echo "root: intro.ipynb" >> $toc_file # Make sure this file exists
echo "title: Play" >> $toc_file
echo "parts:" >> $toc_file

# Iterate through the acts, files per act, and sub-files per file
for ((i=0; i<$NUMBER_OF_ACTS; i++)); do
  mkdir -p "act_${i}"
  echo "  - caption: Part $(($i + 1))" >> $toc_file
  echo "    chapters:" >> $toc_file
  for ((j=0; j<$NUMBER_OF_FILES_PER_ACT; j++)); do
    mkdir -p "act_${i}/act_${i}_${j}"
    for ((k=0; k<$NUMBER_OF_SUB_FILES_PER_FILE; k++)); do
      mkdir -p "act_${i}/act_${i}_${j}/act_${i}_${j}_${k}"
      for ((n=1; n<=$NUMBER_OF_NOTEBOOKS; n++)); do
        new_file="act_${i}/act_${i}_${j}/act_${i}_${j}_${k}/act_${i}_${j}_${k}_${n}.ipynb"
        touch "$new_file"
        cp "intro.ipynb" "$new_file" # This line copies the content into the new file
        echo "      - file: $new_file" >> $toc_file
      done
    done
  done
done

# Create _config.yml file
config_file="_config.yml"
echo "title: Your Book Title" > $config_file
echo "copyright: Mwaka" > $config_file
echo "author: Your Name" >> $config_file
echo "logo: https://raw.githubusercontent.com/jhutrc/jhutrc.github.io/main/hub_and_spoke.jpg" >> $config_file

# Build the book with Jupyter Book
cd ..
jb build $SUBDIR_NAME
git clone "https://github.com/$GITHUB_USERNAME/$REPO_NAME"
cp -r $SUBDIR_NAME/* $REPO_NAME
cd $REPO_NAME
git add ./*
git commit -m "$GIT_COMMIT_MESSAGE"
chmod 600 $SSH_KEY_PATH

# Configure the remote URL with SSH
git remote set-url origin "git@github.com:$GITHUB_USERNAME/$REPO_NAME"

# Push changes
git push -u origin main
ghp-import -n -p -f _build/html
rm -rf $REPO_NAME
echo "Jupyter Book content updated and pushed to $GITHUB_USERNAME/$REPO_NAME repository!"

2 dirstructure#

Here’s a more detailed textual representation of the directory structure created by the script, aiming to clarify the relationships between directories, subdirectories, and sub-subdirectories:

ROOT_DIR (user-specified root directory; e.g., ~dropbox/1f.ἡἔρις,κ/1.ontology)
│
├── SUBDIR_NAME (subdirectory created within root directory)   ├── intro.ipynb
│   ├── _config.yml
│   ├── _toc.yml
│   └── act_0 (subdirectory)       ├── act_0_0 (sub-subdirectory)          ├── act_0_0_0 (sub-sub-subdirectory)             ├── act_0_0_0_1.ipynb
│             ├── act_0_0_0_2.ipynb
│             └── ...
│          ├── act_0_0_1 (sub-sub-subdirectory)          └── ...
│                            ├── act_1        ├── act_1_1         ├── act_1_0            ├── act_1_0_0               ├── act_1_0_0_1.ipynb
│             ├── act_1_0_0_2.ipynb
│             └── ...
│          ├── act_1_0_1            └── ...
│                            ├── act_2        ├── act_2_1         ├── act_2_0            ├── act_2_0_0               ├── act_2_0_0_1.ipynb
│             ├── act_2_0_0_2.ipynb
│             └── ...
│          ├── act_2_0_1            └── ...
│          └── ...
│                           └── ...
├── REPO_NAME (cloned GitHub repository)   ├── same content as SUBDIR_NAME (including subdirectories and files)
└── ...

Explanation:

  • ROOT_DIR: The user-specified root directory.

  • SUBDIR_NAME: A subdirectory created within the root directory, specified by the user.

  • act_X: Subdirectories within SUBDIR_NAME, representing acts in a play.

  • act_X_Y: Sub-subdirectories within each act, representing files for each act.

  • act_X_Y_Z: Sub-sub-subdirectories within each file, containing individual .ipynb files.

  • REPO_NAME: A cloned GitHub repository, which is copied with the content of SUBDIR_NAME, including all the subdirectories and files.

The above structure illustrates how acts, files within acts, and individual .ipynb files are organized within the directory structure. The exact depth and complexity would depend on the specific values set for NUMBER_OF_ACTS, NUMBER_OF_FILES_PER_ACT, NUMBER_OF_SUB_FILES_PER_FILE, and NUMBER_OF_NOTEBOOKS.

3 branch#

Creating a new branch to overhaul the backend structure is a great way to experiment with changes without affecting the main branch. If you’re satisfied with the new structure, you can merge it back into the main branch. Here’s how you can do that:

  1. Ensure You’re in the Right Directory: Navigate to the directory where your local copy of the repository is located using a command-line interface.

  2. Fetch the Latest Changes: Make sure your local copy is up to date with the remote repository by running:

    git pull origin main
    

    Replace main with the name of your default branch if it’s not called “main.”

  3. Create a New Branch: Create a new branch where you can make your changes. You might call it something descriptive like “new-backend.” Run:

    git checkout -b new-backend
    
  4. Make Your Changes: You can now start working on your new backend structure in this branch. Feel free to make any changes you like.

  5. Commit Your Changes: As you make changes, commit them to your branch with:

    git add .
    git commit -m "Description of the changes made"
    
  6. Push the Branch: If you want to push this branch to the remote repository (perhaps for backup or to share with others), run:

    git push origin new-backend
    
  7. Test Thoroughly: Before merging the changes into the main branch, make sure to thoroughly test the new backend to ensure it works as expected.

  8. Merge the Branch: Once you’re satisfied with the new backend structure, you can merge the branch back into the main branch. Here’s how:

    git checkout main
    git merge new-backend
    
  9. Push the Changes: To update the remote repository with your new backend structure, run:

    git push origin main
    
  10. Clean Up: If you want, you can delete the local branch now that it’s been merged:

git branch -d new-backend

By using a branch, you’re keeping all the history of your changes, and you have the flexibility to experiment without affecting the existing code. If something goes wrong, you can always switch back to the main branch, and your changes will be safe in the separate branch.


4 restructure#

git clone https://github.com/muzaale/got
cd got  
git pull origin main  
git checkout -b new-backend  
cd ..

# new template to emulate
cp -r yafe/* got 

# copy specific .ipynb files from the old structure to the new structure
cp  got/git_0/git_1_1.ipynb got/act_5/act_5_9/act_5_9_0/act_5_9_0_1.ipynb
cp  got/git_0/git_1_2.ipynb got/act_5/act_5_9/act_5_9_0/act_5_9_0_2.ipynb
cp  got/git_1/git_2_1.ipynb got/act_5/act_5_9/act_5_9_0/act_5_9_0_3.ipynb
cp  got/git_3/git_4_1.ipynb got/act_5/act_5_9/act_5_9_1/act_5_9_1_1.ipynb
cp  got/git_5/git_6_7.ipynb got/act_5/act_5_9/act_5_9_1/act_5_9_1_2.ipynb

# relocate all .dta files from the old structure to the new structure
for i in {0..6}; do
  if [ -d "got/git_$i" ] && [ -n "$(ls -A got/git_$i/*.dta 2>/dev/null)" ]; then
    mv got/git_$i/*.dta got/act_5/act_5_9/
  fi
done
for i in {0..6}; do
  rm -r got/git_$i
done

# rename the new structure to the old structure
rm -r git
mv got git
cd git
git add .

# massive commit message
git commit -m "
git clone https://github.com/muzaale/got
cd got  
git pull origin main  
git checkout -b new-backend  
cd ..
cp -r yafe/* got 
cp  got/git_0/git_1_1.ipynb got/act_5/act_5_9/act_5_9_0/act_5_9_0_1.ipynb
cp  got/git_0/git_1_2.ipynb got/act_5/act_5_9/act_5_9_0/act_5_9_0_2.ipynb
cp  got/git_1/git_2_1.ipynb got/act_5/act_5_9/act_5_9_0/act_5_9_0_3.ipynb
cp  got/git_3/git_4_1.ipynb got/act_5/act_5_9/act_5_9_1/act_5_9_1_1.ipynb
cp  got/git_5/git_6_7.ipynb got/act_5/act_5_9/act_5_9_1/act_5_9_1_2.ipynb
for i in {0..6}; do
  if [ -d "got/git_$i" ] && [ -n "$(ls -A got/git_$i/*.dta 2>/dev/null)" ]; then
    mv got/git_$i/*.dta got/act_5/act_5_9/
  fi
done
for i in {0..6}; do
  rm -r got/git_$i
done
mv got get
git add .
git commit -m xxx"

# push the new structure to the new-backend branch
chmod 600 ~/.ssh/id_gitgot
git remote set-url origin "git@github.com:muzaale/new-backend"
git checkout main
git merge new-backend
git remote -v
ssh-add -D 
chmod 600 ~/.ssh/id_gitgot
git remote set-url origin "git@github.com:muzaale/got"
ssh-add "$(eval echo ~/.ssh/id_gitgot)"
git config --local user.name "muzaale"
git config --local user.email "muzaale@gmail.com"
git push origin main
ghp-import -n -p -f _build/html

5. output#

 rename git_0/git_1_1.ipynb => act_5/act_5_9/act_5_9_0/act_5_9_0_1.ipynb (100%)
 rename git_0/git_1_2.ipynb => act_5/act_5_9/act_5_9_0/act_5_9_0_2.ipynb (100%)
 rename git_1/git_2_1.ipynb => act_5/act_5_9/act_5_9_0/act_5_9_0_3.ipynb (100%)
 rename git_3/git_4_1.ipynb => act_5/act_5_9/act_5_9_1/act_5_9_1_1.ipynb (100%)
 rename git_5/git_6_7.ipynb => act_5/act_5_9/act_5_9_1/act_5_9_1_2.ipynb (100%)
 create mode 100644 act_5/act_5_9/act_5_9_1/act_5_9_1_3.ipynb
 rename {git_6 => act_5/act_5_9}/cod.dta (100%)
 rename {git_5 => act_5/act_5_9}/donor_live_esrd.dta (100%)
 rename {git_5 => act_5/act_5_9}/donor_live_keep.dta (100%)
 rename {git_6 => act_5/act_5_9}/esrd.dta (100%)
 rename {git_6 => act_5/act_5_9}/esrd_pt.dta (100%)
 rename {git_6 => act_5/act_5_9}/malignancy.dta (100%)
 rename {git_6 => act_5/act_5_9}/p2010anemia_summary.dta (100%)
 rename {git_6 => act_5/act_5_9}/p2010artall.dta (100%)
 rename {git_6 => act_5/act_5_9}/p2010bmi.dta (100%)
 rename {git_6 => act_5/act_5_9}/p2010ckd_long.dta (100%)
 rename {git_6 => act_5/act_5_9}/p2010ckd_summary.dta (100%)
 rename {git_6 => act_5/act_5_9}/p2010diab_summary.dta (100%)
 rename {git_6 => act_5/act_5_9}/p2010haart1st.dta (100%)
 rename {git_6 => act_5/act_5_9}/p2010hcv_summary.dta (100%)
 rename {git_6 => act_5/act_5_9}/p2010ht_long.dta (100%)
 rename {git_6 => act_5/act_5_9}/p2010ht_summary.dta (100%)
 rename {git_6 => act_5/act_5_9}/p2010lipid_summary.dta (100%)
 rename {git_6 => act_5/act_5_9}/p2010nadi.dta (100%)
 rename {git_6 => act_5/act_5_9}/p2010smoking_tf_imputed.dta (100%)
 rename {git_6 => act_5/act_5_9}/p2010vlsum2.dta (100%)
 rename {git_6 => act_5/act_5_9}/patient.dta (100%)
 rename {git_6 => act_5/act_5_9}/tcellsum.dta (100%)

6. push#

cd git
git branch
git checkout new-backend
git add .
git commit -m "_toc.yml didn't include act_5"
git remote -v
ssh-add -D 
chmod 600 ~/.ssh/id_gitgot
git remote set-url origin "git@github.com:muzaale/got"
ssh-add "$(eval echo ~/.ssh/id_gitgot)"
git config --local user.name "muzaale"
git config --local user.email "muzaale@gmail.com"
git push origin main
ghp-import -n -p -f _build/html
git push origin new-backend

7. oldstructure#

If you want to remove the old structure from the gh-pages branch, you’ll need to first switch to that branch, then delete the files and directories as required, and finally commit and push the changes. Here’s how you can do that:

  1. Switch to the gh-pages Branch:

    git checkout gh-pages
    
  2. Delete the Old Structure: You’ll need to manually delete the files and directories that constitute the old structure. Use the rm command for files and rm -r for directories. For example, if you need to delete a directory called old_directory:

    rm -r old_directory
    
  3. Stage the Deletion: Since you’ve removed files, you’ll need to stage these changes:

    git add -A
    
  4. Commit the Changes:

    git commit -m "Removed old structure from gh-pages branch"
    
  5. Push the Changes to the Remote Repository:

    git push origin gh-pages
    

Now the old structure has been removed from the gh-pages branch both locally and in the remote repository.

If you’re uncertain about which files and directories need to be removed, you might want to carefully review the branch’s contents before proceeding, perhaps consulting any documentation or team members involved in the project. Remember, deleting files is a significant action and can’t easily be undone, so take care to ensure that you’re removing only what’s necessary.


8. newstructure#

You can replace the contents of the main branch with the contents of the new-backend branch while preserving the commit histories of both branches. Here’s how you can do it:

  1. Clone the repository if you don’t have it locally:

    git clone https://github.com/muzaale/got.git
    cd got
    
  2. Fetch all branches:

    git fetch origin
    
  3. Check out the main branch:

    git checkout main
    
  4. Merge the new-backend branch into main without committing automatically:

    git merge new-backend --no-commit --no-ff
    
  5. Resolve any merge conflicts if they exist. You can use a tool like VS Code or manually edit the files. Once you’ve resolved the conflicts, add the resolved files:

    git add -A
    
  6. Commit the merge:

    git commit -m "Merged new-backend into main"
    
  7. Push the changes to the remote repository:

    git push origin main
    

This process will merge the new-backend branch into the main branch, keeping the commit history of both branches. Make sure you have the necessary permissions to push changes to the remote repository.

If you wish to replace the contents entirely without merging, you can create a new branch based on new-backend and force-push it to main. Be cautious with this approach, as it will overwrite the main branch, and the changes will be non-recoverable if not backed up elsewhere.


a more seamless process would be to use the git subtree command. This command allows you to merge the contents of one branch into another branch while preserving the commit history of both branches. Here’s how you can do it:

  1. Clone the repository if you don’t have it locally:

    git clone
    cd got
    
  2. Fetch all branches:

    git fetch origin
    
  3. Check out the main branch:

    git checkout main
    
  4. Merge the new-backend branch into main:

    git subtree merge --prefix=git new-backend --squash
    
  5. Push the changes to the remote repository:

    git push origin main
    

This process will merge the new-backend branch into the main branch, keeping the commit history of both branches. Make sure you have the necessary permissions to push changes to the remote repository.


what i did was to create a new branch called new-backend and then merge it into the main branch. This way, the commit history of both branches is preserved. Here’s how you can do it (see earlier). but for the sake of my gh-pages, see what i did in the next section.


9. finale#

rm -rf git/_build
abi/abikesa_jbc5.sh