[{"data":1,"prerenderedAt":1121},["ShallowReactive",2],{"docs-navigation":3,"doc-\u002Fteaching\u002Fapps-dev\u002Fcheat-sheets\u002Fgithub-collaboration":229,"surround-\u002Fteaching\u002Fapps-dev\u002Fcheat-sheets\u002Fgithub-collaboration":919,"notes-index":924},[4,88,171,182,192,203,218],{"title":5,"path":6,"stem":7,"children":8},"Dev","\u002Fdev","1.dev",[9,12,26,36,50,56,78],{"title":10,"path":6,"stem":11},"Development","1.dev\u002Findex",{"title":13,"path":14,"stem":15,"children":16},"Laravel","\u002Fdev\u002Flaravel","1.dev\u002F1.laravel\u002Findex",[17,18,22],{"title":13,"path":14,"stem":15},{"title":19,"path":20,"stem":21},"Eloquent Relationships","\u002Fdev\u002Flaravel\u002Feloquent-relationships","1.dev\u002F1.laravel\u002F1.eloquent-relationships",{"title":23,"path":24,"stem":25},"Laravel Homestead","\u002Fdev\u002Flaravel\u002Flaravel-homestead","1.dev\u002F1.laravel\u002F2.laravel-homestead",{"title":27,"path":28,"stem":29,"children":30},"Bash","\u002Fdev\u002Fbash","1.dev\u002F13.bash\u002Findex",[31,32],{"title":27,"path":28,"stem":29},{"title":33,"path":34,"stem":35},"My Bash RC","\u002Fdev\u002Fbash\u002Fbash-rc","1.dev\u002F13.bash\u002F2.bash-rc",{"title":37,"path":38,"stem":39,"children":40},"Clean Code","\u002Fdev\u002Fclean-code","1.dev\u002F15.clean-code\u002Findex",[41,42,46],{"title":37,"path":38,"stem":39},{"title":43,"path":44,"stem":45},"Naming Things","\u002Fdev\u002Fclean-code\u002Fnaming-things","1.dev\u002F15.clean-code\u002F1.naming-things",{"title":47,"path":48,"stem":49},"Services Return, Callers Present","\u002Fdev\u002Fclean-code\u002Fservices-return-callers-present","1.dev\u002F15.clean-code\u002F2.services-return-callers-present",{"title":51,"path":52,"stem":53,"children":54},"AI Prompting","\u002Fdev\u002Fai-prompting","1.dev\u002F17.ai-prompting\u002Findex",[55],{"title":51,"path":52,"stem":53},{"title":57,"path":58,"stem":59,"children":60},"C#","\u002Fdev\u002Fcsharp","1.dev\u002F2.csharp\u002Findex",[61,62,66,70,74],{"title":57,"path":58,"stem":59},{"title":63,"path":64,"stem":65},"C# Basics","\u002Fdev\u002Fcsharp\u002Fcsharp-basics","1.dev\u002F2.csharp\u002F1.csharp-basics",{"title":67,"path":68,"stem":69},"Classes & Models","\u002Fdev\u002Fcsharp\u002Fclasses-and-models","1.dev\u002F2.csharp\u002F2.classes-and-models",{"title":71,"path":72,"stem":73},"Services & Helpers","\u002Fdev\u002Fcsharp\u002Fservices-and-helpers","1.dev\u002F2.csharp\u002F3.services-and-helpers",{"title":75,"path":76,"stem":77},"Project Structure","\u002Fdev\u002Fcsharp\u002Fproject-structure","1.dev\u002F2.csharp\u002F4.project-structure",{"title":79,"path":80,"stem":81,"children":82},"Git","\u002Fdev\u002Fgit","1.dev\u002F9.git\u002Findex",[83,84],{"title":79,"path":80,"stem":81},{"title":85,"path":86,"stem":87},"Git Cheat Sheet","\u002Fdev\u002Fgit\u002Fgit-cheat-sheet","1.dev\u002F9.git\u002F1.git-cheat-sheet",{"title":89,"path":90,"stem":91,"children":92},"Teaching","\u002Fteaching","2.teaching",[93,95],{"title":89,"path":90,"stem":94},"2.teaching\u002Findex",{"title":96,"path":97,"stem":98,"children":99},"AppsDev","\u002Fteaching\u002Fapps-dev","2.teaching\u002F1.apps-dev\u002Findex",[100,101,119,137,147,161],{"title":96,"path":97,"stem":98},{"title":102,"path":103,"stem":104,"children":105},"Lesson Plans","\u002Fteaching\u002Fapps-dev\u002Flesson-plans","2.teaching\u002F1.apps-dev\u002F1.lesson-plans\u002Findex",[106,107,111,115],{"title":102,"path":103,"stem":104},{"title":108,"path":109,"stem":110},"Coding with AI","\u002Fteaching\u002Fapps-dev\u002Flesson-plans\u002Fcoding-with-ai","2.teaching\u002F1.apps-dev\u002F1.lesson-plans\u002F1.coding-with-ai",{"title":112,"path":113,"stem":114},"Coding with AI: Prompts & Reading JavaScript","\u002Fteaching\u002Fapps-dev\u002Flesson-plans\u002Fprompts-and-reading-js","2.teaching\u002F1.apps-dev\u002F1.lesson-plans\u002F2.prompts-and-reading-js",{"title":116,"path":117,"stem":118},"JavaScript for Beginners","\u002Fteaching\u002Fapps-dev\u002Flesson-plans\u002Fjavascript-for-beginners","2.teaching\u002F1.apps-dev\u002F1.lesson-plans\u002F3.javascript-for-beginners",{"title":120,"path":121,"stem":122,"children":123},"Activities","\u002Fteaching\u002Fapps-dev\u002Factivities","2.teaching\u002F1.apps-dev\u002F2.activities\u002Findex",[124,125,129,133],{"title":120,"path":121,"stem":122},{"title":126,"path":127,"stem":128},"Dynamic Portfolio Website","\u002Fteaching\u002Fapps-dev\u002Factivities\u002Fdynamic-portfolio-website","2.teaching\u002F1.apps-dev\u002F2.activities\u002F2.dynamic-portfolio-website",{"title":130,"path":131,"stem":132},"Mini Product Store","\u002Fteaching\u002Fapps-dev\u002Factivities\u002Fmini-product-store","2.teaching\u002F1.apps-dev\u002F2.activities\u002F3.mini-product-store",{"title":134,"path":135,"stem":136},"Semester Project","\u002Fteaching\u002Fapps-dev\u002Factivities\u002Fsemester-project","2.teaching\u002F1.apps-dev\u002F2.activities\u002F4.semester-project",{"title":138,"path":139,"stem":140,"children":141},"Exercises","\u002Fteaching\u002Fapps-dev\u002Fexercises","2.teaching\u002F1.apps-dev\u002F4.exercises\u002Findex",[142,143],{"title":138,"path":139,"stem":140},{"title":144,"path":145,"stem":146},"Read & Predict","\u002Fteaching\u002Fapps-dev\u002Fexercises\u002Fread-and-predict","2.teaching\u002F1.apps-dev\u002F4.exercises\u002F1.read-and-predict",{"title":148,"path":149,"stem":150,"children":151},"AI Prompts","\u002Fteaching\u002Fapps-dev\u002Fai-prompts","2.teaching\u002F1.apps-dev\u002F7.ai-prompts\u002Findex",[152,153,157],{"title":148,"path":149,"stem":150},{"title":154,"path":155,"stem":156},"Prompt Flow","\u002Fteaching\u002Fapps-dev\u002Fai-prompts\u002Fbasic-prompting","2.teaching\u002F1.apps-dev\u002F7.ai-prompts\u002F1.basic-prompting",{"title":158,"path":159,"stem":160},"Using OpenCode CLI Instead of Copy-Pasting from ChatGPT","\u002Fteaching\u002Fapps-dev\u002Fai-prompts\u002Fopencode-cli","2.teaching\u002F1.apps-dev\u002F7.ai-prompts\u002F2.opencode-cli",{"title":162,"path":163,"stem":164,"children":165},"Cheat Sheets","\u002Fteaching\u002Fapps-dev\u002Fcheat-sheets","2.teaching\u002F1.apps-dev\u002F8.cheat-sheets\u002Findex",[166,167],{"title":162,"path":163,"stem":164},{"title":168,"path":169,"stem":170},"How to Collaborate on GitHub","\u002Fteaching\u002Fapps-dev\u002Fcheat-sheets\u002Fgithub-collaboration","2.teaching\u002F1.apps-dev\u002F8.cheat-sheets\u002F1.github-collaboration",{"title":172,"path":173,"stem":174,"children":175},"Snippets","\u002Fsnippets","3.snippets",[176,178],{"title":172,"path":173,"stem":177},"3.snippets\u002Findex",{"title":179,"path":180,"stem":181},"Debounce and Throttle","\u002Fsnippets\u002Fdebounce-and-throttle","3.snippets\u002F1.debounce-and-throttle",{"title":162,"path":183,"stem":184,"children":185},"\u002Fcheat-sheets","4.cheat-sheets",[186,188],{"title":162,"path":183,"stem":187},"4.cheat-sheets\u002Findex",{"title":189,"path":190,"stem":191},"Vim Cheat Sheet","\u002Fcheat-sheets\u002Fvim-cheat-sheet","4.cheat-sheets\u002F1.vim-cheat-sheet",{"title":193,"path":194,"stem":195,"children":196},"Templates","\u002Ftemplates","5.templates",[197,199],{"title":193,"path":194,"stem":198},"5.templates\u002Findex",{"title":200,"path":201,"stem":202},"Pull Request Template","\u002Ftemplates\u002Fpull-request-template","5.templates\u002F1.pull-request-template",{"title":204,"path":205,"stem":206,"children":207},"Meta","\u002Fmeta","6.meta",[208,210,214],{"title":204,"path":205,"stem":209},"6.meta\u002Findex",{"title":211,"path":212,"stem":213},"Authoring Guide","\u002Fmeta\u002Fauthoring-guide","6.meta\u002F1.authoring-guide",{"title":215,"path":216,"stem":217},"Markdown Showcase","\u002Fmeta\u002Fmarkdown-showcase","6.meta\u002F2.markdown-showcase",{"title":219,"path":220,"stem":221,"children":222},"Troubleshooting","\u002Ftroubleshooting","7.troubleshooting",[223,225],{"title":219,"path":220,"stem":224},"7.troubleshooting\u002Findex",{"title":226,"path":227,"stem":228},"Fixing CORS Errors","\u002Ftroubleshooting\u002Fcors-errors","7.troubleshooting\u002F1.cors-errors",{"id":230,"title":168,"body":231,"category":162,"createdAt":898,"description":899,"draft":900,"extension":901,"featured":900,"keywords":902,"links":909,"meta":910,"navigation":911,"path":169,"readingTime":453,"seo":912,"stem":170,"tags":913,"updatedAt":898,"__hash__":918},"docs\u002F2.teaching\u002F1.apps-dev\u002F8.cheat-sheets\u002F1.github-collaboration.md",{"type":232,"value":233,"toc":873},"minimark",[234,242,253,258,265,279,283,338,342,506,510,580,584,587,601,604,607,611,614,618,621,664,673,677,684,692,699,703,706,718,721,756,769,773,860,864,869],[235,236,237,238,241],"p",{},"One team, one repository, everybody pushing to it. This is the setup for the\n",[239,240,134],"a",{"href":135}," — follow it\nonce at the start and you're done.",[243,244,245],"note",{},[235,246,247,248,252],{},"Only ",[249,250,251],"strong",{},"one person"," creates the repository. The rest of the team joins it as\ncollaborators. Four repositories is not a team project, it's four solo projects\nthat happen to have the same name.",[254,255,257],"h2",{"id":256},"before-you-start","Before You Start",[235,259,260,261,264],{},"Every member of the team needs their ",[249,262,263],{},"own GitHub account",". No exceptions, no\nsharing an account.",[235,266,267,268,274,275,278],{},"Sign up at ",[239,269,273],{"href":270,"rel":271},"https:\u002F\u002Fgithub.com",[272],"nofollow","github.com"," with an email you'll still have\naccess to at the end of the semester. Write down your ",[249,276,277],{},"username"," — your\nteammates need it to add you.",[254,280,282],{"id":281},"create-the-repository","Create the Repository",[284,285,287,292,299,306,310,317,332],"steps",{"level":286},"3",[288,289,291],"h3",{"id":290},"click-new","Click New",[235,293,294,295,298],{},"From your GitHub dashboard, click the ",[249,296,297],{},"New"," button.",[235,300,301],{},[302,303],"img",{"alt":304,"src":305},"The GitHub dashboard with the green New repository button highlighted","https:\u002F\u002Fres.cloudinary.com\u002Fdu6rliaeg\u002Fimage\u002Fupload\u002Fv1785597171\u002Fclick-new_yfuldd.webp",[288,307,309],{"id":308},"name-it-and-create-it","Name it and create it",[235,311,312,313,316],{},"Give it your project name, then click ",[249,314,315],{},"Create repository",".",[235,318,319,320,324,325,328,329,316],{},"Use a name that says what the project is — ",[321,322,323],"code",{},"cafe-order-system",", not ",[321,326,327],{},"project","\nor ",[321,330,331],{},"finalproject2",[235,333,334],{},[302,335],{"alt":336,"src":337},"The new repository form with the repository name filled in and the Create repository button below","https:\u002F\u002Fres.cloudinary.com\u002Fdu6rliaeg\u002Fimage\u002Fupload\u002Fv1785597172\u002Fname-the-repository_bxbphe.webp",[254,339,341],{"id":340},"push-your-project","Push Your Project",[284,343,344,348,357,363,373,377,383,389,396,496,500,503],{"level":286},[288,345,347],{"id":346},"open-a-terminal-inside-your-project-folder","Open a terminal inside your project folder",[235,349,350,351,328,354,316],{},"Go to your project folder, right-click inside it, and choose ",[249,352,353],{},"Open in Terminal",[249,355,356],{},"Open Git Bash here",[235,358,359],{},[302,360],{"alt":361,"src":362},"Windows right-click context menu inside a project folder showing the Open in Terminal option","https:\u002F\u002Fres.cloudinary.com\u002Fdu6rliaeg\u002Fimage\u002Fupload\u002Fv1785597172\u002Fopen-terminal-in-project_p103wc.webp",[364,365,366],"warning",{},[235,367,368,369,372],{},"Make sure the terminal opens ",[249,370,371],{},"inside"," the project folder, not one level above\nit. Push from the wrong folder and you'll upload the wrong files.",[288,374,376],{"id":375},"follow-the-instructions-github-gives-you","Follow the instructions GitHub gives you",[235,378,379,380,316],{},"Your empty repository page shows the exact commands to run. Use the block\nlabelled ",[249,381,382],{},"\"…or push an existing repository from the command line\"",[235,384,385],{},[302,386],{"alt":387,"src":388},"The GitHub quick setup page showing the command line instructions for pushing an existing repository","https:\u002F\u002Fres.cloudinary.com\u002Fdu6rliaeg\u002Fimage\u002Fupload\u002Fv1785597171\u002Ffollow-git-instructions_xufgqv.webp",[235,390,391,392,395],{},"The commands look like this — copy them from ",[249,393,394],{},"your"," page, since the URL is\ndifferent for every repository:",[397,398,403],"pre",{"className":399,"code":400,"language":401,"meta":402,"style":402},"language-bash shiki shiki-themes material-theme-lighter vitesse-light vitesse-dark","git init\ngit add .\ngit commit -m \"first commit\"\ngit branch -M main\ngit remote add origin https:\u002F\u002Fgithub.com\u002FUSERNAME\u002FREPO-NAME.git\ngit push -u origin main\n","bash","",[321,404,405,418,429,451,465,481],{"__ignoreMap":402},[406,407,410,414],"span",{"class":408,"line":409},"line",1,[406,411,413],{"class":412},"sYn-s","git",[406,415,417],{"class":416},"sTbE_"," init\n",[406,419,421,423,426],{"class":408,"line":420},2,[406,422,413],{"class":412},[406,424,425],{"class":416}," add",[406,427,428],{"class":416}," .\n",[406,430,432,434,437,441,445,448],{"class":408,"line":431},3,[406,433,413],{"class":412},[406,435,436],{"class":416}," commit",[406,438,440],{"class":439},"sz9Cv"," -m",[406,442,444],{"class":443},"sbYkP"," \"",[406,446,447],{"class":416},"first commit",[406,449,450],{"class":443},"\"\n",[406,452,454,456,459,462],{"class":408,"line":453},4,[406,455,413],{"class":412},[406,457,458],{"class":416}," branch",[406,460,461],{"class":439}," -M",[406,463,464],{"class":416}," main\n",[406,466,468,470,473,475,478],{"class":408,"line":467},5,[406,469,413],{"class":412},[406,471,472],{"class":416}," remote",[406,474,425],{"class":416},[406,476,477],{"class":416}," origin",[406,479,480],{"class":416}," https:\u002F\u002Fgithub.com\u002FUSERNAME\u002FREPO-NAME.git\n",[406,482,484,486,489,492,494],{"class":408,"line":483},6,[406,485,413],{"class":412},[406,487,488],{"class":416}," push",[406,490,491],{"class":439}," -u",[406,493,477],{"class":416},[406,495,464],{"class":416},[288,497,499],{"id":498},"reload-the-page","Reload the page",[235,501,502],{},"Refresh your repository page. Your files should now be listed there.",[235,504,505],{},"If the page still shows the setup instructions, the push didn't work — read the\nerror message in your terminal.",[254,507,509],{"id":508},"add-your-teammates","Add Your Teammates",[284,511,512,516,523,529,533,543,549,553,559,562,568],{"level":286},[288,513,515],{"id":514},"click-settings","Click Settings",[235,517,518,519,522],{},"Open the ",[249,520,521],{},"Settings"," tab of your repository.",[235,524,525],{},[302,526],{"alt":527,"src":528},"A GitHub repository page with the Settings tab highlighted","https:\u002F\u002Fres.cloudinary.com\u002Fdu6rliaeg\u002Fimage\u002Fupload\u002Fv1785597172\u002Fsettings_jq2edj.webp",[288,530,532],{"id":531},"go-to-collaborators-then-add-people","Go to Collaborators, then Add people",[235,534,535,536,539,540,316],{},"In the left sidebar, choose ",[249,537,538],{},"Collaborators",", then click ",[249,541,542],{},"Add people",[235,544,545],{},[302,546],{"alt":547,"src":548},"The Collaborators settings page with the Add people button","https:\u002F\u002Fres.cloudinary.com\u002Fdu6rliaeg\u002Fimage\u002Fupload\u002Fv1785597171\u002Fcollaborators-then-add-peopls_rjjxbp.webp",[288,550,552],{"id":551},"type-their-username-or-email","Type their username or email",[235,554,555,556,316],{},"Enter your teammate's GitHub username or email, then click\n",[249,557,558],{},"Add to repository",[235,560,561],{},"Repeat for every teammate.",[235,563,564],{},[302,565],{"alt":566,"src":567},"The add collaborator dialog with a username typed in and the Add to repository button","https:\u002F\u002Fres.cloudinary.com\u002Fdu6rliaeg\u002Fimage\u002Fupload\u002Fv1785597173\u002Ftype-username-or-email_aday15.webp",[364,569,570,577],{},[235,571,572,573,576],{},"Each teammate must ",[249,574,575],{},"accept the invitation"," before they can push. It arrives by\nemail and also appears in their GitHub notifications.",[235,578,579],{},"An unaccepted invitation looks exactly like a working setup right up until the\nmoment someone tries to push and gets rejected.",[254,581,583],{"id":582},"your-teammates-join","Your Teammates Join",[235,585,586],{},"Once they've accepted, each teammate clones the repository onto their own\nmachine:",[397,588,590],{"className":399,"code":589,"language":401,"meta":402,"style":402},"git clone https:\u002F\u002Fgithub.com\u002FUSERNAME\u002FREPO-NAME.git\n",[321,591,592],{"__ignoreMap":402},[406,593,594,596,599],{"class":408,"line":409},[406,595,413],{"class":412},[406,597,598],{"class":416}," clone",[406,600,480],{"class":416},[235,602,603],{},"Use the owner's username in that URL — the repo lives in one place and everyone\nclones the same one.",[235,605,606],{},"That's it. They can now push to the repository.",[254,608,610],{"id":609},"before-anyone-writes-code","Before Anyone Writes Code",[235,612,613],{},"Two things to do once, on every machine.",[288,615,617],{"id":616},"set-your-git-identity","Set your Git identity",[235,619,620],{},"Use your own name and the email attached to your GitHub account:",[397,622,624],{"className":399,"code":623,"language":401,"meta":402,"style":402},"git config --global user.name \"Your Name\"\ngit config --global user.email \"you@example.com\"\n",[321,625,626,646],{"__ignoreMap":402},[406,627,628,630,633,636,639,641,644],{"class":408,"line":409},[406,629,413],{"class":412},[406,631,632],{"class":416}," config",[406,634,635],{"class":439}," --global",[406,637,638],{"class":416}," user.name",[406,640,444],{"class":443},[406,642,643],{"class":416},"Your Name",[406,645,450],{"class":443},[406,647,648,650,652,654,657,659,662],{"class":408,"line":420},[406,649,413],{"class":412},[406,651,632],{"class":416},[406,653,635],{"class":439},[406,655,656],{"class":416}," user.email",[406,658,444],{"class":443},[406,660,661],{"class":416},"you@example.com",[406,663,450],{"class":443},[243,665,666],{},[235,667,668,669,672],{},"This is what makes your commits show up as ",[249,670,671],{},"yours",". Your contribution grade is\nread straight off the repository's commit history, so get this right before your\nfirst commit — not after.",[288,674,676],{"id":675},"add-a-gitignore","Add a .gitignore",[235,678,679,680,683],{},"Create a file called ",[321,681,682],{},".gitignore"," in the project root:",[397,685,690],{"className":686,"code":688,"filename":682,"language":689,"meta":402},[687],"language-text","node_modules\u002F\n.env\n*.log\n.DS_Store\n","text",[321,691,688],{"__ignoreMap":402},[235,693,694,695,698],{},"Never commit ",[321,696,697],{},"node_modules\u002F",". It's thousands of files your teammates already\nhave, and it makes the repository unusable.",[254,700,702],{"id":701},"the-daily-loop","The Daily Loop",[235,704,705],{},"Every time you sit down to work:",[397,707,709],{"className":399,"code":708,"language":401,"meta":402,"style":402},"git pull\n",[321,710,711],{"__ignoreMap":402},[406,712,713,715],{"class":408,"line":409},[406,714,413],{"class":412},[406,716,717],{"class":416}," pull\n",[235,719,720],{},"Work, then:",[397,722,724],{"className":399,"code":723,"language":401,"meta":402,"style":402},"git add .\ngit commit -m \"describe what you changed\"\ngit push\n",[321,725,726,734,749],{"__ignoreMap":402},[406,727,728,730,732],{"class":408,"line":409},[406,729,413],{"class":412},[406,731,425],{"class":416},[406,733,428],{"class":416},[406,735,736,738,740,742,744,747],{"class":408,"line":420},[406,737,413],{"class":412},[406,739,436],{"class":416},[406,741,440],{"class":439},[406,743,444],{"class":443},[406,745,746],{"class":416},"describe what you changed",[406,748,450],{"class":443},[406,750,751,753],{"class":408,"line":431},[406,752,413],{"class":412},[406,754,755],{"class":416}," push\n",[757,758,759],"tip",{},[235,760,761,764,765,768],{},[321,762,763],{},"git pull"," ",[249,766,767],{},"before"," you start, every single time. Four people editing the same\nrepository will conflict eventually — pulling first turns \"an evening lost to a\nmerge\" into \"ten seconds of nothing happening.\"",[254,770,772],{"id":771},"when-something-goes-wrong","When Something Goes Wrong",[774,775,776,789],"table",{},[777,778,779],"thead",{},[780,781,782,786],"tr",{},[783,784,785],"th",{},"Problem",[783,787,788],{},"What to do",[790,791,792,808,821,831,846],"tbody",{},[780,793,794,805],{},[795,796,797,800,801,804],"td",{},[321,798,799],{},"Permission denied"," \u002F ",[321,802,803],{},"403"," on push",[795,806,807],{},"You weren't added, or you never accepted the invitation",[780,809,810,815],{},[795,811,812],{},[321,813,814],{},"rejected — fetch first",[795,816,817,818,820],{},"Someone pushed before you. Run ",[321,819,763],{},", fix any conflicts, push again",[780,822,823,828],{},[795,824,825],{},[321,826,827],{},"not a git repository",[795,829,830],{},"Your terminal is in the wrong folder",[780,832,833,836],{},[795,834,835],{},"Pushed the wrong files",[795,837,838,839,841,842,845],{},"Add them to ",[321,840,682],{},", then ",[321,843,844],{},"git rm -r --cached \u003Cfolder>"," and commit",[780,847,848,851],{},[795,849,850],{},"I have no idea what I changed",[795,852,853,856,857],{},[321,854,855],{},"git status"," and ",[321,858,859],{},"git diff",[254,861,863],{"id":862},"full-command-reference","Full Command Reference",[235,865,866,867,316],{},"More Git commands than you'll need this semester:\n",[239,868,85],{"href":86},[870,871,872],"style",{},"html pre.shiki code .sYn-s, html code.shiki .sYn-s{--shiki-light:#E2931D;--shiki-default:#59873A;--shiki-dark:#80A665}html pre.shiki code .sTbE_, html code.shiki .sTbE_{--shiki-light:#91B859;--shiki-default:#B56959;--shiki-dark:#C98A7D}html pre.shiki code .sz9Cv, html code.shiki .sz9Cv{--shiki-light:#91B859;--shiki-default:#A65E2B;--shiki-dark:#C99076}html pre.shiki code .sbYkP, html code.shiki .sbYkP{--shiki-light:#39ADB5;--shiki-default:#B5695977;--shiki-dark:#C98A7D77}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":402,"searchDepth":431,"depth":431,"links":874},[875,876,880,885,890,891,895,896,897],{"id":256,"depth":420,"text":257},{"id":281,"depth":420,"text":282,"children":877},[878,879],{"id":290,"depth":431,"text":291},{"id":308,"depth":431,"text":309},{"id":340,"depth":420,"text":341,"children":881},[882,883,884],{"id":346,"depth":431,"text":347},{"id":375,"depth":431,"text":376},{"id":498,"depth":431,"text":499},{"id":508,"depth":420,"text":509,"children":886},[887,888,889],{"id":514,"depth":431,"text":515},{"id":531,"depth":431,"text":532},{"id":551,"depth":431,"text":552},{"id":582,"depth":420,"text":583},{"id":609,"depth":420,"text":610,"children":892},[893,894],{"id":616,"depth":431,"text":617},{"id":675,"depth":431,"text":676},{"id":701,"depth":420,"text":702},{"id":771,"depth":420,"text":772},{"id":862,"depth":420,"text":863},"2026-08-01","Create one repository, push your project, and add your teammates as collaborators so the whole team can work on the same code.",false,"md",[903,904,905,906,907,908],"github collaborators","add people to repository","push existing project to github","git init","clone repository","group project github",[],{},true,{"title":168,"description":899},[914,413,915,916,917],"github","collaboration","teamwork","setup","xeFM65rVnxyEkSOxlBBys1L5TQNAbBWclBdpKv3uCiw",[920,922],{"title":162,"path":163,"stem":164,"description":921,"children":-1},"Step-by-step references students can follow on their own during class.",{"title":172,"path":173,"stem":177,"description":923,"children":-1},"Small, copy-ready fragments you reach for again and again.",[925,934,936,938,946,954,962,967,970,973,976,984,990,993,998,1001,1007,1010,1013,1018,1021,1024,1030,1034,1039,1042,1048,1052,1055,1060,1063,1066,1069,1072,1074,1080,1082,1087,1090,1094,1097,1104,1109,1112,1118],{"path":135,"title":134,"description":926,"tags":927,"category":120,"featured":900,"updatedAt":898,"createdAt":898,"readingTime":933,"draft":900},"Teams of four build one frontend application over the whole semester using AI, in a single shared GitHub repository where everyone contributes.",[928,929,930,914,931,932],"teaching","activity","capstone","ai","frontend",12,{"path":169,"title":168,"description":899,"tags":935,"category":162,"featured":900,"updatedAt":898,"createdAt":898,"readingTime":453,"draft":900},[914,413,915,916,917],{"path":163,"title":162,"description":921,"tags":937,"category":162,"featured":900,"updatedAt":898,"createdAt":898,"readingTime":409,"draft":900},[],{"path":159,"title":158,"description":939,"tags":940,"category":148,"featured":900,"updatedAt":945,"createdAt":945,"readingTime":431,"draft":900},"Install and configure the OpenCode CLI so AI writes code directly into your project folder instead of you copying it from a chat window.",[931,941,942,943,944],"opencode","cli","tooling","workflow","2026-07-25",{"path":48,"title":47,"description":947,"tags":948,"category":37,"featured":900,"updatedAt":953,"createdAt":953,"readingTime":420,"draft":900},"A service should return a result and let the caller decide how to show it — the single most useful separation-of-concerns rule.",[949,950,951,952],"clean-code","architecture","separation-of-concerns","services","2026-07-19",{"path":64,"title":63,"description":955,"tags":956,"category":961,"featured":900,"updatedAt":953,"createdAt":953,"readingTime":431,"draft":900},"Types, variables, control flow and how to write a function (method) in C#, mapped from PHP.",[957,958,959,960],"csharp","dotnet","basics","functions",null,{"path":68,"title":67,"description":963,"tags":964,"category":961,"featured":900,"updatedAt":953,"createdAt":953,"readingTime":431,"draft":900},"Create a class, give it properties and a constructor, and use it — the C# version of a Laravel model.",[957,958,965,966],"classes","models",{"path":72,"title":71,"description":968,"tags":969,"category":961,"featured":900,"updatedAt":953,"createdAt":953,"readingTime":431,"draft":900},"Put code in another file — a service or a static helper — and call it from anywhere, the C# way.",[957,958,952,950],{"path":76,"title":75,"description":971,"tags":972,"category":961,"featured":900,"updatedAt":953,"createdAt":953,"readingTime":431,"draft":900},"How C# files, namespaces, folders and the dotnet CLI fit together into a running app.",[957,958,943,950],{"path":58,"title":57,"description":974,"tags":975,"category":961,"featured":900,"updatedAt":953,"createdAt":953,"readingTime":409,"draft":900},"Learning C# and .NET from a Laravel\u002FPHP background — the fundamentals, mapped to what you already know.",[957,958,959],{"path":20,"title":19,"description":977,"tags":978,"category":13,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},"The core Eloquent relationship types with examples and the N+1 trap to avoid.",[979,980,981,982],"laravel","eloquent","database","orm","2026-07-17",{"path":24,"title":23,"description":985,"tags":986,"category":13,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},"My quick reference for setting up and using Laravel Homestead during development.",[979,987,988,989],"homestead","vagrant","virtualbox",{"path":14,"title":13,"description":991,"tags":992,"category":13,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},"The PHP framework for web artisans — Eloquent, routing, queues and more.",[],{"path":34,"title":33,"description":994,"tags":995,"category":27,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":420,"draft":900},"Personal Bash aliases and helper functions that streamline my Laravel and Homestead development workflow.",[401,996,997,987,979],"bashrc","git bash",{"path":28,"title":27,"description":999,"tags":1000,"category":27,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},"Shell scripting and a faster life on the command line.",[],{"path":44,"title":43,"description":1002,"tags":1003,"category":37,"featured":911,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},"Practical rules for naming variables, functions and types so code reads like prose.",[949,1004,1005,1006],"naming","readability","craft",{"path":38,"title":37,"description":1008,"tags":1009,"category":37,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},"Writing code that other people (and future you) can read.",[],{"path":52,"title":51,"description":1011,"tags":1012,"category":51,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},"Getting reliable, useful results out of language models.",[],{"path":86,"title":85,"description":1014,"tags":1015,"category":79,"featured":911,"updatedAt":983,"createdAt":983,"readingTime":420,"draft":900},"The Git commands I actually use day to day, plus how to undo things safely.",[413,942,1016,1017],"version-control","cheat-sheet",{"path":80,"title":79,"description":1019,"tags":1020,"category":79,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},"Version control — everyday commands and getting out of trouble.",[],{"path":6,"title":10,"description":1022,"tags":1023,"category":10,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},"Languages, frameworks and the craft of building software.",[],{"path":109,"title":108,"description":1025,"tags":1026,"category":89,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":453,"draft":900},"An introduction to AI-assisted software development, modern development workflows, and the mindset needed to use AI responsibly throughout the course.",[931,1027,1028,1029],"software development","prompt engineering","beginners",{"path":113,"title":112,"description":1031,"tags":1032,"category":89,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":453,"draft":900},"Learn how to write effective AI prompts and read JavaScript code confidently. This lesson teaches students how to direct AI instead of blindly copying its output.",[931,1033,1028,1029],"javascript",{"path":117,"title":116,"description":1035,"tags":1036,"category":89,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":431,"draft":900},"Introduction to the fundamentals of JavaScript, from variables and functions to loops, DOM manipulation, and events. This lesson prepares students for the Mini Product Store activity.",[1033,1029,1037,1038],"programming","web development",{"path":103,"title":102,"description":1040,"tags":1041,"category":102,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},"Session-by-session plans with objectives, timing and materials.",[],{"path":127,"title":126,"description":1043,"tags":1044,"category":120,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":431,"draft":900},"Build a personal portfolio website using JavaScript arrays, loops, and DOM manipulation instead of hardcoded HTML.",[928,929,1033,1045,1046,1047],"portfolio","dom","loops",{"path":131,"title":130,"description":1049,"tags":1050,"category":120,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":431,"draft":900},"A JavaScript activity where students build a simple product store using arrays, loops, functions, DOM manipulation, and event listeners.",[928,929,1033,1046,1051,1047],"arrays",{"path":121,"title":120,"description":1053,"tags":1054,"category":120,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},"In-class activities that get students doing, not just listening.",[],{"path":145,"title":144,"description":1056,"tags":1057,"category":120,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":420,"draft":900},"Practice reading JavaScript code, predicting its output, and verifying your understanding before running the program.",[928,929,1033,960,1058,1059],"if-statement","debugging",{"path":139,"title":138,"description":1061,"tags":1062,"category":138,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},"Practice problems that build skill through repetition.",[],{"path":155,"title":154,"description":1064,"tags":1065,"category":148,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":453,"draft":900},"A structured workflow for working with AI that emphasizes planning, review, and understanding before implementation.",[931,1028,944],{"path":149,"title":148,"description":1067,"tags":1068,"category":148,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},"Prompt templates for teaching with and about AI.",[],{"path":97,"title":96,"description":1070,"tags":1071,"category":89,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},"Lesson plans, activities, rubrics and student references.",[],{"path":90,"title":89,"description":1070,"tags":1073,"category":89,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},[],{"path":180,"title":179,"description":1075,"tags":1076,"category":172,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},"Two tiny functions to control how often a handler runs — with the difference explained.",[1033,1077,1078,1079],"performance","snippets","events",{"path":173,"title":172,"description":923,"tags":1081,"category":172,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},[],{"path":190,"title":189,"description":1083,"tags":1084,"category":162,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},"The essential Vim motions and commands to get productive and get out.",[1085,1086,1017,942],"vim","editor",{"path":183,"title":162,"description":1088,"tags":1089,"category":162,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},"Dense, scannable references for commands and syntax.",[],{"path":201,"title":200,"description":1091,"tags":1092,"category":193,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},"A reusable PR description template that makes reviews faster and kinder.",[413,914,1093,915],"template",{"path":194,"title":193,"description":1095,"tags":1096,"category":193,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},"Reusable starting points for files, configs and docs.",[],{"path":212,"title":211,"description":1098,"tags":1099,"category":204,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":420,"draft":900},"The frontmatter and markdown conventions every note in this knowledge base follows.",[1100,1101,1102,1103],"meta","conventions","markdown","authoring",{"path":216,"title":215,"description":1105,"tags":1106,"category":204,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":420,"draft":900},"Every formatting feature this knowledge base supports, on one page — a living reference and rendering test.",[1102,1107,1108],"mdc","reference",{"path":205,"title":204,"description":1110,"tags":1111,"category":204,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},"How this knowledge base itself is built and maintained.",[],{"path":227,"title":226,"description":1113,"tags":1114,"category":219,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},"What a CORS error actually means and how to fix it — on the server, where it belongs.",[1115,1116,1117,1059],"cors","http","apis",{"path":220,"title":219,"description":1119,"tags":1120,"category":219,"featured":900,"updatedAt":983,"createdAt":983,"readingTime":409,"draft":900},"Symptoms, causes and fixes for problems worth remembering.",[],1785598842133]