{"id":"l-git-3-1","courseId":"git-github","lang":"en","kind":"lesson","summary":"Connect your portfolio to a GitHub repository, push branches with upstream tracking, and keep in sync using fetch and pull while understanding what origin/main really is.","html":"<p>So far the portfolio exists in one place, your laptop. If the disk dies, it’s gone, and nobody else can see or review it. A <strong>remote</strong> is another copy of the repository somewhere else, usually on GitHub. Git’s job is to keep the two in sync, and it does that with four main commands: <code dir=\"ltr\">clone</code>, <code dir=\"ltr\">fetch</code>, <code dir=\"ltr\">pull</code> and <code dir=\"ltr\">push</code>.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">Put the portfolio on GitHub</h2>\n<p>On github.com, create a new repository named <code dir=\"ltr\">portfolio</code>. Leave “Add a README” and the other initialisation options unticked: your local repository already has history, and an extra commit on GitHub would give you two unrelated histories to reconcile. GitHub then shows the commands to connect an existing repository. They boil down to:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"bash\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">Terminal</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">git</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> remote</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> add</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> origin</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> https://github.com/maya-okafor/portfolio.git</span></span>\n<span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">git</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> remote</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> -v</span></span>\n<span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">git</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> push</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> -u</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> origin</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> main</span></span></code></pre></div>\n<p><code dir=\"ltr\">git remote add</code> gives a URL a short name. <strong>origin</strong> is only a convention, the name Git uses automatically when you clone, but everyone uses it, so do too. The push uploads your commits and creates <code dir=\"ltr\">main</code> on GitHub. The first time, Git will ask you to authenticate; the next lesson covers setting that up properly with SSH keys or a credential manager.</p>\n<p>If you use the GitHub CLI, <code dir=\"ltr\">gh repo create portfolio --public --source=. --remote=origin --push</code> does the whole thing in one go.</p>\n<p>Starting from the other side, with a repository that already exists on GitHub, you clone it instead:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"bash\" data-index=\"1\"><div class=\"code-head\"><span class=\"code-title\">Terminal</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">git</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> clone</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> https://github.com/maya-okafor/portfolio.git</span></span></code></pre></div>\n<p>Clone creates the folder, downloads every commit, adds a remote called <code dir=\"ltr\">origin</code> and checks out <code dir=\"ltr\">main</code> with tracking already set up.</p>\n<h2 id=\"sec-2\" tabindex=\"-1\">Remote-tracking branches: Git’s memory of the remote</h2>\n<p>After the push, <code dir=\"ltr\">git branch -a</code> shows something new:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"text\" data-index=\"2\"><div class=\"code-head\"><span class=\"code-title\">Text</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code>* main\n  remotes/origin/main</code></pre></div>\n<p><code dir=\"ltr\">origin/main</code> is a <strong>remote-tracking branch</strong>: your repository’s note of where <code dir=\"ltr\">main</code> was on <code dir=\"ltr\">origin</code> the last time you talked to it. You never commit to it. It moves only when you fetch, pull or push. That’s why <code dir=\"ltr\">git status</code> can say “Your branch is up to date with ‘origin/main’” while a teammate pushed five minutes ago: Git hasn’t asked GitHub since.</p>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 700 270\" role=\"img\" aria-labelledby=\"l-git-3-1-t1\"><defs><marker id=\"arrow-l-git-3-1-1\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\"><path d=\"M0 0 L10 5 L0 10 z\" class=\"d-arrowhead\"/></marker></defs>\n  <title id=\"l-git-3-1-t1\">Left, your laptop: main points at c3; origin/main, your last-known copy, points at b2. Right, GitHub: main points at d4, a commit a teammate pushed. git fetch downloads d4 and moves origin/main; git pull then also integrates it into your main; git push sends your commits and moves GitHub's main.</title>\n  <rect class=\"d-box\" x=\"20\" y=\"20\" width=\"330\" height=\"230\" rx=\"14\"/>\n  <text class=\"d-label-strong\" x=\"40\" y=\"48\">Your laptop</text>\n  <circle class=\"d-box\" cx=\"70\" cy=\"130\" r=\"22\"/>\n  <text class=\"d-code\" x=\"70\" y=\"135\" text-anchor=\"middle\">b2</text>\n  <circle class=\"d-box-primary\" cx=\"170\" cy=\"130\" r=\"22\"/>\n  <text class=\"d-code\" x=\"170\" y=\"135\" text-anchor=\"middle\">c3</text>\n  <path class=\"d-line\" d=\"M148 130 L92 130\"/>\n  <rect class=\"d-box-accent\" x=\"135\" y=\"70\" width=\"70\" height=\"30\" rx=\"8\"/>\n  <text class=\"d-code\" x=\"170\" y=\"90\" text-anchor=\"middle\">main</text>\n  <rect class=\"d-box-warn\" x=\"25\" y=\"175\" width=\"100\" height=\"30\" rx=\"8\"/>\n  <text class=\"d-code\" x=\"75\" y=\"195\" text-anchor=\"middle\">origin/main</text>\n  <path class=\"d-line\" d=\"M70 152 L70 175\"/>\n  <text class=\"d-label-muted\" x=\"40\" y=\"236\">origin/main: last seen at b2</text>\n  <rect class=\"d-box\" x=\"440\" y=\"20\" width=\"240\" height=\"230\" rx=\"14\"/>\n  <text class=\"d-label-strong\" x=\"460\" y=\"48\">GitHub (origin)</text>\n  <circle class=\"d-box\" cx=\"490\" cy=\"130\" r=\"22\"/>\n  <text class=\"d-code\" x=\"490\" y=\"135\" text-anchor=\"middle\">b2</text>\n  <circle class=\"d-box-success\" cx=\"600\" cy=\"130\" r=\"22\"/>\n  <text class=\"d-code\" x=\"600\" y=\"135\" text-anchor=\"middle\">d4</text>\n  <path class=\"d-line\" d=\"M578 130 L512 130\"/>\n  <rect class=\"d-box-accent\" x=\"565\" y=\"70\" width=\"70\" height=\"30\" rx=\"8\"/>\n  <text class=\"d-code\" x=\"600\" y=\"90\" text-anchor=\"middle\">main</text>\n  <text class=\"d-label-muted\" x=\"460\" y=\"200\">d4: a teammate's push</text>\n  <path class=\"d-arrow\" d=\"M440 110 L354 110\" marker-end=\"url(#arrow-l-git-3-1-1)\"/>\n  <text class=\"d-code\" x=\"397\" y=\"100\" text-anchor=\"middle\">fetch</text>\n  <path class=\"d-arrow\" d=\"M354 160 L440 160\" marker-end=\"url(#arrow-l-git-3-1-1)\"/>\n  <text class=\"d-code\" x=\"397\" y=\"182\" text-anchor=\"middle\">push</text>\n</svg><figcaption>Your branch, your note about the remote, and the remote itself</figcaption></figure>\n<h2 id=\"sec-3\" tabindex=\"-1\">Upstreams and git push -u</h2>\n<p>The <code dir=\"ltr\">-u</code> in <code dir=\"ltr\">git push -u origin main</code> (long form <code dir=\"ltr\">--set-upstream</code>) records that your local <code dir=\"ltr\">main</code> <strong>tracks</strong> <code dir=\"ltr\">origin/main</code>. From then on:</p>\n<ul>\n<li>a bare <code dir=\"ltr\">git push</code> or <code dir=\"ltr\">git pull</code> on <code dir=\"ltr\">main</code> knows where to go;</li>\n<li><code dir=\"ltr\">git status</code> reports “ahead 2” or “behind 1” against <code dir=\"ltr\">origin/main</code>;</li>\n<li><code dir=\"ltr\">git branch -vv</code> lists each branch with its upstream and ahead/behind counts.</li>\n</ul>\n<p>Every new branch needs it once, on its first push: <code dir=\"ltr\">git push -u origin footer</code>.</p>\n<h2 id=\"sec-4\" tabindex=\"-1\">Fetch, then pull</h2>\n<p><code dir=\"ltr\">git fetch</code> asks the remote what’s new, downloads the commits and moves your remote-tracking branches. It never touches your own branches or files, so it’s always safe:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"bash\" data-index=\"3\"><div class=\"code-head\"><span class=\"code-title\">Terminal</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">git</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> fetch</span></span>\n<span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">git</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> status</span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">                       # \"Your branch is behind 'origin/main' by 1 commit\"</span></span>\n<span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">git</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> log</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> --oneline</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> main..origin/main</span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">   # what's new over there</span></span></code></pre></div>\n<p><code dir=\"ltr\">git pull</code> is <code dir=\"ltr\">git fetch</code> followed by integrating the upstream into your current branch. If you have no local commits of your own, that’s a fast-forward. If both sides have new commits, Git has to merge or rebase, and recent Git versions refuse to guess:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"text\" data-index=\"4\"><div class=\"code-head\"><span class=\"code-title\">Text</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code>fatal: Need to specify how to reconcile divergent branches.</code></pre></div>\n<p>Make the choice once:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"bash\" data-index=\"5\"><div class=\"code-head\"><span class=\"code-title\">Terminal</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">git</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> config</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> --global</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> pull.rebase</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> true</span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">    # replay my unpushed commits on top (my default)</span></span>\n<span class=\"line\"><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># or: git config --global pull.rebase false   (create a merge commit)</span></span>\n<span class=\"line\"><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># or: git config --global pull.ff only        (refuse unless it's a fast-forward)</span></span></code></pre></div>\n<p>I recommend <code dir=\"ltr\">pull.rebase true</code>. It only rewrites your own unpushed commits, which the golden rule allows, and it keeps history free of “Merge branch ‘main’ of github.com:…” commits that say nothing.</p>\n<h2 id=\"sec-5\" tabindex=\"-1\">A daily rhythm</h2>\n<p>Put these together and a working session on the portfolio looks the same every time. Start by switching to <code dir=\"ltr\">main</code> and pulling, so you begin from what’s actually on GitHub rather than what was there last week. Create a branch for the change. Commit as you go, and push the branch early, even unfinished: a pushed branch is a backup, and it’s visible to anyone helping you. Before you open it for review, fetch again and rebase onto the fresh <code dir=\"ltr\">origin/main</code> if it has moved. That habit alone prevents most of the rejected pushes and surprise conflicts people blame on Git.</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"bash\" data-index=\"6\"><div class=\"code-head\"><span class=\"code-title\">Terminal</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">git</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> switch</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> main</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> &#x26;&#x26; </span><span style=\"color:#953800;--shiki-dark:#FFA657\">git</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> pull</span></span>\n<span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">git</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> switch</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> -c</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> projects-filter</span></span>\n<span class=\"line\"><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># …work and commit…</span></span>\n<span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">git</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> push</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> -u</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> origin</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> projects-filter</span></span></code></pre></div>\n<h2 id=\"sec-6\" tabindex=\"-1\">When push is rejected</h2>\n<p>If someone pushed to <code dir=\"ltr\">main</code> since your last fetch, your push is refused:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"text\" data-index=\"7\"><div class=\"code-head\"><span class=\"code-title\">Text</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code> ! [rejected]        main -&gt; main (fetch first)\nerror: failed to push some refs to 'https://github.com/maya-okafor/portfolio.git'</code></pre></div>\n<p>The remote has commits you don’t. Pull them in, resolve any conflict with the routine from section 2, run your checks, and push again.</p>\n<aside class=\"callout callout-mistake\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/></svg><span><span class=\"callout-kind\">Common mistake</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>Forcing past a rejected push</span></p>\n<p>The rejection exists because pushing would throw away someone else’s commits. <code dir=\"ltr\">git push --force</code> does exactly that, and it’s the single most common way people lose a teammate’s work. On a shared branch the fix is always <code dir=\"ltr\">git pull</code>, then <code dir=\"ltr\">git push</code>.</p>\n</aside>\n<aside class=\"callout callout-tip\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5\"/><path d=\"M9 18h6\"/><path d=\"M10 22h4\"/></svg><span><span class=\"callout-kind\">Tip</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>Keep your branch list honest</span></p>\n<p>When branches are deleted on GitHub after merging, your <code dir=\"ltr\">origin/footer</code> notes linger. <code dir=\"ltr\">git fetch --prune</code> removes them, and <code dir=\"ltr\">git config --global fetch.prune true</code> makes every fetch do it.</p>\n</aside>\n<p>Your first push asked for credentials. Next you’ll set up authentication properly, so Git stops asking and GitHub knows it’s really you.</p>\n","toc":[{"id":"sec-1","text":"Put the portfolio on GitHub","level":2},{"id":"sec-2","text":"Remote-tracking branches: Git’s memory of the remote","level":2},{"id":"sec-3","text":"Upstreams and git push -u","level":2},{"id":"sec-4","text":"Fetch, then pull","level":2},{"id":"sec-5","text":"A daily rhythm","level":2},{"id":"sec-6","text":"When push is rejected","level":2}],"takeaways":["A remote is a named URL for another copy of the repository; <code dir=\"ltr\">origin</code> is the conventional name for the one you cloned from or push to.","<code dir=\"ltr\">origin/main</code> is your local record of where <code dir=\"ltr\">main</code> was on the remote at your last fetch; it moves only when you fetch, pull or push.","<code dir=\"ltr\">git push -u origin &lt;branch&gt;</code> uploads a branch and sets it as the upstream, so later a bare <code dir=\"ltr\">git push</code> or <code dir=\"ltr\">git pull</code> knows where to go.","<code dir=\"ltr\">git fetch</code> downloads without touching your branches; <code dir=\"ltr\">git pull</code> fetches and then merges or rebases.","A rejected push means the remote has commits you don’t; pull them in, then push again, never force."],"further":[{"title":"Working with Remotes (Pro Git)","url":"https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes"},{"title":"Remote Branches (Pro Git)","url":"https://git-scm.com/book/en/v2/Git-Branching-Remote-Branches"},{"title":"Pushing commits to a remote repository","url":"https://docs.github.com/en/get-started/using-git/pushing-commits-to-a-remote-repository"},{"title":"git pull reference","url":"https://git-scm.com/docs/git-pull"}],"quiz":[{"q":"<p>You ran <code dir=\"ltr\">git fetch</code> and it downloaded two new commits on <code dir=\"ltr\">main</code>. What changed in your working tree?</p>","options":[{"text":"Your files now include the two new commits’ changes.","why":"That’s what <code dir=\"ltr\">git pull</code> does in its second step. <code dir=\"ltr\">git fetch</code> alone never touches your files or branches."},{"text":"Your local <code dir=\"ltr\">main</code> moved forward by two commits.","why":"Fetch updates remote-tracking branches like <code dir=\"ltr\">origin/main</code>, never your own <code dir=\"ltr\">main</code>."},{"text":"The two commits were merged and a merge commit was created.","why":"No merge happens on fetch. You choose when and how to integrate."},{"text":"Nothing; only <code dir=\"ltr\">origin/main</code> moved, and your files and <code dir=\"ltr\">main</code> are unchanged.","why":"Correct. Fetching is always safe. Compare with <code dir=\"ltr\">git log main..origin/main</code> before deciding to merge or rebase."}],"answer":3},{"q":"<p><code dir=\"ltr\">git push</code> fails with: <code dir=\"ltr\">Updates were rejected because the remote contains work that you do not have locally.</code> What’s the right fix?</p>","options":[{"text":"Run <code dir=\"ltr\">git pull</code> to bring in the remote commits, resolve anything that conflicts, then <code dir=\"ltr\">git push</code> again.","why":"Correct. The remote has commits you lack; integrate them first, and your push becomes a fast-forward."},{"text":"Run <code dir=\"ltr\">git push --force</code> so your version wins.","why":"That would delete the commits someone else pushed. Force-pushing is never the fix for a shared branch being ahead."},{"text":"Delete your local repository and clone it again.","why":"You’d lose your unpushed commits. Pulling integrates both sides without losing anything."},{"text":"Run <code dir=\"ltr\">git push -u origin main</code> to reset the tracking.","why":"Tracking isn’t the problem. The remote branch has moved on and your push can’t fast-forward it."}],"answer":0},{"q":"<p>What does <code dir=\"ltr\">-u</code> add to <code dir=\"ltr\">git push -u origin footer</code>?</p>","options":[{"text":"It uploads untracked files along with the commits.","why":"Pushes only ever send commits. Untracked files aren’t part of any commit."},{"text":"It makes the push faster by skipping verification.","why":"<code dir=\"ltr\">-u</code> stands for <code dir=\"ltr\">--set-upstream</code>. It has nothing to do with speed or checks."},{"text":"It records <code dir=\"ltr\">origin/footer</code> as the upstream of your local <code dir=\"ltr\">footer</code>, so later <code dir=\"ltr\">git push</code> and <code dir=\"ltr\">git pull</code> need no arguments.","why":"Correct. It’s needed once per branch; afterwards <code dir=\"ltr\">git status</code> also reports ahead/behind counts against <code dir=\"ltr\">origin/footer</code>."},{"text":"It updates every branch on the remote, not only <code dir=\"ltr\">footer</code>.","why":"Only the branch you name is pushed. <code dir=\"ltr\">--all</code> exists for pushing every branch."}],"answer":2},{"q":"<p>Your local <code dir=\"ltr\">main</code> has one commit you haven’t pushed, and <code dir=\"ltr\">origin/main</code> has two you haven’t pulled. With <code dir=\"ltr\">pull.rebase</code> set to <code dir=\"ltr\">true</code>, what does <code dir=\"ltr\">git pull</code> do?</p>","options":[{"text":"Creates a merge commit joining your commit and the two remote ones.","why":"That’s the behaviour with <code dir=\"ltr\">pull.rebase false</code>. With <code dir=\"ltr\">true</code>, Git rebases instead of merging."},{"text":"Fetches, then replays your unpushed commit on top of the two remote commits.","why":"Correct. History stays linear, and only your own unpushed commit is rewritten, which respects the golden rule."},{"text":"Refuses, because the branches have diverged.","why":"That’s what <code dir=\"ltr\">pull.ff only</code> does. <code dir=\"ltr\">pull.rebase true</code> handles divergence by rebasing."}],"answer":1}],"exercise":{"kind":"fill","language":"bash","template":"git remote {{0}} origin https://github.com/maya-okafor/portfolio.git\ngit push {{1}} origin main      # first push: also set the upstream\n\n# later: see what's new on GitHub without touching my files\ngit {{2}}\ngit log --oneline main..origin/main","blanks":[{"answers":["add"]},{"answers":["-u","--set-upstream"]},{"answers":["fetch","fetch origin"]}],"title":"Connect and sync the portfolio","prompt":"<p>Fill in the blanks: register the GitHub repository as <code dir=\"ltr\">origin</code>, push <code dir=\"ltr\">main</code> for the first time so it tracks <code dir=\"ltr\">origin/main</code>, and later check for new commits on GitHub without changing your branch or files.</p>\n","hints":["<code dir=\"ltr\">git remote</code> has a subcommand that registers a new name and URL.","The push flag that records the upstream is a single letter, short for upstream.","One of the four sync commands downloads without integrating."],"explanation":"<p><code dir=\"ltr\">git remote add origin &lt;url&gt;</code> names the GitHub URL <code dir=\"ltr\">origin</code>. <code dir=\"ltr\">git push -u origin main</code> uploads <code dir=\"ltr\">main</code> and sets <code dir=\"ltr\">origin/main</code> as its upstream, so a bare <code dir=\"ltr\">git push</code> or <code dir=\"ltr\">git pull</code> works from then on. <code dir=\"ltr\">git fetch</code> updates <code dir=\"ltr\">origin/main</code> without touching <code dir=\"ltr\">main</code> or your files; <code dir=\"ltr\">git log main..origin/main</code> then lists exactly what you’d get by pulling.</p>\n","checkLabels":{}},"words":778,"readMinutes":4}