Feature request: add `submit` command

Open
#19 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
25/100
Issue type
Feature
Clarity
Needs clarification
Activity status
Stale
Tech stack
git, github, go, python

Research direction

Start with the proposed gh classroom submit command forms and the pseudocode in this issue; no implementation files or tests are identified. Define done as a working extension that submits the selected directory to the specified repository and branch while respecting the stated Git workflow and conflict constraints.

Written by the indexing model from the issue text.

Description

Premise

Git is hard for students in introductory courses (e.g., CS1). Particularly at term's start, when commands like

python foo.py

or

gcc foo.c
./a.out

are already quite new to many students (and complicated if something goes wrong), it's just not compelling to add the cognitive overhead of, or instructional time for, commands like

git add
git commit
git push

in the earliest days of a course, particularly if Git, early on, is used primarily for submitting work (and not yet for actual collaboration or versioning).

Much like computer science itself teaches abstraction, and much like instructional scaffolding characterizes many curricula, so can (and, daresay, should) Git be abstracted away until such time as a teacher's students are ready for lessons in Git itself.

Solution

Provide students with a gh classroom submit command that automates the requisite git-add, git-commit, and git-push commands via which to submit their work, executed a la

gh classroom submit ORG/REPO [DIR]

or

gh classroom submit ORG/REPO@BRANCH [DIR]

wherein ORG is a teacher's org (for GitHub Classroom), REPO is a student's repo therein, BRANCH is an optional branch therein, and DIR is the directory to submit (i.e., push to the remote repo), which would default to $PWD.

Alternatively, per @octosteve, a student could be prompted interactively to select an assignment to submit.

Implementation Details

Underneath the hood, gh-classroom-submit would be a GitHub CLI extension:

  1. Clone a student's repo to, e.g., /tmp (and optionally check out a particular branch).
  2. Effectively remove the contents thereof.
  3. Copy the contents of $PWD to that directory, git adding and committing the same.
  4. Push the commit back to the remote repo.

For maximum compatibility and ease of installation, probably best if gh-classroom-submit is implemented as an interpreted extension in Python and distributed via PyPI. That way, students can use it having just Python on their PC or Mac, without additionally needing the GitHub CLI itself, installation of which could be a tad more involved, especially for less comfortable students.

Alternatively, if interactive prompts are compelling, using Go might be best, if only to use the same terminal-based GUI libraries that other extensions are using. Pre-installation in students' Codespaces, too, would be trivial to automate.

Pseudocode

Assumes $ORG, $REPO, and optionally $BRANCH are already set, as via command-line arguments or sensible defaults.

#!/usr/bin/bash

# We'll clone a bare repo here
export GIT_DIR=$(mktemp -d)

# We'll assume the student's work is in $PWD
export GIT_WORK_TREE="$PWD"

# Clone the remote's .git directory
git clone --bare "git@github.com:$ORG/$REPO" "$GIT_DIR"

# We'll "submit" to this branch
git symbolic-ref HEAD "refs/heads/$BRANCH"

# Let's check out the teacher's .gitignore from the student's remote clone thereof
git checkout main .gitignore

# Let's add everything from $PWD, modulo the .gitignore
git add --all

# Represent this submission with a commit
git commit --allow-empty --allow-empty-message --message ""

# Push the submission to the remote branch
git push origin "refs/heads/$BRANCH"
Upsides

This approach would avoid any merge conflicts altogether (by first cloning the remote repo), as might (all too frequently) happen if a student accepts an assignment, clones the repo locally, starts to make changes locally, and unwittingly then makes changes (and commits) remotely, as via GitHub.com's pencil icon.

Students also have a habit of deleting things they shouldn't, if only because they don't recognize them (e.g., a .git directory in their local clone). Alternatively, if students happen to create a new folder locally into which they cp their work (not realizing their original folder also had a "hidden" .git folder), they might end up without a local repo altogether from which to push. (And the solution then would be a convoluted, manual git-clone, then an rm, then another cp or mv or the like, every step of which would (all too frequently) be fraught with potential pitfalls.

To reduce the probability of mistakes and FAQs, then, much better to automate and abstract (at least at term's start) the submission process entirely.

Alternatives

To resolve cases in which students have induced merge conflicts, as by editing a file on GitHub.com via the pencil icon but wanting to submit different code locally, we could force-push. But any solution that risks overwriting history and/or losing work isn't ideal and is best to avoid.

Similarly could we try to resolve what would otherwise be merge conflicts with -Xours, but that, too, would risk overwriting remote work that would be best to preserve.

Alternatively still, if a student's state resembles

remote:  A - B - C
local:       \ D - E

we could try to achieve

remote: A - B - C - F
local: A - B - C - F

wherein F == E, but that would overwrite local history (i.e., commits), which is likely to confuse students who consciously made those local commits.

Best, then, for gh-classroom-submit to be a consistent abstraction, ignoring the local repo (i.e., .git) altogether and worrying only about getting the student's local code to the remote, without losing history locally or remotely. A student could thus actually use Git locally, particularly when learning it for the first time. But submissions would be entirely independent of that local history.

In cases where a student (or teacher) wants students local commits to be reflected in their remote repo, that's when it's time for the "training wheels" to come off, replacing the abstraction that is gh-classroom-submit with actual git commands that students themselves execute.

Dominant language
Go
Stars
126
Forks
21
PR merge metrics
No merged PRs in 30d

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from github/gh-classroom

All issues in github/gh-classroom

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.