will give you a git repo without a working set (just the contents typically in the .git directory). This allows you to create things like `foo.git` instead of `foo/.git`.
“origin” is also just the default name for the cloned remote. It could be called anything, and you can have as many remotes as you’d like. You can even namespace where you push back to the same remotes by changing fetch and push paths. At one company it was common to push back to `$user/$feature` to avoid polluting the root namespace with personal branches. It was also common to have `backup/$user` for pushing having a backup of an entire local repo.
I often add a hostname namespace when I’m working from multiple hosts and then push between them directly to another instead of going back to a central server.
For a small static site repo that has documents and server config, I have a remote like:
So I can push from my computer directly to that server, but those branches won’t overwrite the server’s branches. It acts like a reverse `git pull`, which can be useful for firewalls and other situations where my laptop wouldn’t be routable.
is another good one to know, it also makes a bare repository that is an exact clone (including all branches, tags, notes, etc) of a remote repo. Unlike a normal clone that is set up for local tracking branches of the remote.
It doesn't include pull requests, when cloning from github, though.
> It doesn't include pull requests, when cloning from github, though.
Because GitHub pull requests are a proprietary, centralized, cloud-dependent reimplementation of `git request-pull`.
How the "free software" world slid head first into a proprietary cloud-based "open source" world still boils my blood. Congrats, Microsoft loves and owns it all, isn't that what what we always wanted?
When this kind of “sliding” happens it’s usually because the base implementation was missing functionality. Turns out CLI interfaces by themselves are (from a usability perspective) incomplete for the kind of collaboration git was designed to facilitate.
In another post discussion, someone suggested git as an alternative to overleaf, a Google Docs for latex... I guess there are plenty of people with blind spots for things that are technically possible, and usabel to experts, and UI that actually empowers much broader classes of users to wield the feature.
If you actually use the live collaboration features of overleaf, sure, it’s not a replacement. But lots of people use overleaf to write latex by themselves. The experience is just so much worse than developing locally and tracking changes with git.
> Turns out CLI interfaces by themselves are (from a usability perspective) incomplete for the kind of collaboration git was designed to facilitate.
git was designed to facilitate the collaboration scheme of the Linux Kernel Mailing List, which is, as you might guess... a mailing list.
Rather than a pull-request (which tries to repurpose git's branching infrastructure to support collaboration), the intended unit of in-the-large contribution / collaboration in git is supposed to be the patch.
The patch contribution workflow is entirely CLI-based... if you use a CLI mail client (like Linus Torvalds did at the time git was designed.)
The core "technology" of this is, on the contributor side:
1. "trailer" fields on commits (for things like `Fixes`, `Link`, `Reported-By`, etc)
2. `git format-patch`, with flags like `--cover-letter` (this is where the thing you'd think of as the "PR description" goes), `--reroll-count`, etc.
3. a codebase-specific script like Linux's `./scripts/get_maintainer.pl`, to parse out (from source-file-embedded headers) the set of people to notify explicitly about the patch — this is analogous to a PR's concept of "Assignees" + "Reviewers"
4. `git send-email`, feeding in the patch-series generated in step 2, and targeting the recipients list from step 3. (This sends out a separate email for each patch in the series, but in such a way that the messages get threaded to appear as a single conversation thread in modern email clients.)
And on the maintainer side:
5. `s ~/patches/patch-foo.mbox` (i.e. a command in a CLI email client like mutt(1), in the context of the patch-series thread, to save the thread to an .mbox file)
6. `git am -3 --scissors ~/patches/patch-foo.mbox` to split the patch-series mbox file back into individual patches, convert them back into an annotated commit-series, and build that into a topic branch for testing and merging.
Subsystem maintainers, meanwhile, didn't use patches to get topic branches "upstream" [= in Linus's git repo]. Linus just had the subsystem maintainers as git-remotes, and then, when nudged, fetched their integration branches, reviewed them, and merged them, with any communication about this occurring informally out-of-band. In other words, the patch flow was for low-trust collaboration, while direct fetch was for high-trust collaboration.
Interestingly, in the LKML context, `git request-pull` is simply a formalization of the high-trust collaboration workflow (specifically, the out-of-band "hey, fetch my branches and review them" nudge email). It's not used for contribution, only integration; and it doesn't really do anything you can't do with an email — its only real advantages are in keeping the history of those requests within the repo itself, and for forcing requests to be specified in terms of exact git refs to prevent any confusion.
It still blows my mind how git has lost it's original ideas of decentralized development because of github and how github, a for-profit - centralized - close-sourced forge, became the center for lots of important open source projects. We need radicle, forgejo, gitea to catch up even more!
It's not the interface, it's the web hosting. People want a free destination server that's up 24/7 to store their repository.
If it was only the web interface, people could locally install GitLab or Gitea to get a web browser UI. (Or use whatever modern IDE code editor to have a GUI instead of a CLI for git commands.) But doing that still doesn't solve what GitHub solves: a public server to host the files, issue tracking, etc.
Before git & Github, people put source code for public access on SourceForge and CodeProject. The reason was the same: a zero-cost way to share code with everybody.
> “origin” is also just the default name for the cloned remote. It could be called anything, and you can have as many remotes as you’d like.
One remote can also hold more URLs! This is arguably more obscure (Eclipse's EGit doesn't even support it), but works wonders for my workflow, since I want to push to multiple mirrors at the same time.
Whenever I fork a repo I rename origin to “fork” and then add the parent repo as a remote named “upstream” so i can pull from that, rebase any of my own changes in to, and push to fork as needed.
Multiple remotes is also how you can combine multiple repos into one monorepo by just fetching and pulling from each one, maybe into different subdirectories to avoid path collisions.
I always thought it would have been better, and less confusing for newcomers, if GitHub had named the default remote “github”, instead of origin, in the examples.
Requiring a fork to open pull requests as an outsider to a project is in itself a idiosyncrasy of GitHub that could be done without. Gitea and Forgejo for example support AGit: https://forgejo.org/docs/latest/user/agit-support/.
Nevertheless, to avoid ambiguity I usually name my personal forks on GitHub gh-<username>.
No, it's a normal feature of Git. If I want you to pull my changes, I need to host those changes somewhere that you can access. If you and I are both just using ssh access to our separate Apache servers, for example, I am going to have to push my changes to a fork on my server before you can pull them.
And of course in Git every clone is a fork.
AGit seems to be a new alternative where apparently you can push a new branch to someone else's repository that you don't normally have access to, but that's never guaranteed to be possible, and is certainly very idiosyncratic.
> Requiring a fork to open pull requests as an outsider to a project is in itself a idiosyncrasy of GitHub that could be done without. Gitea and Forgejo for example support AGit: https://forgejo.org/docs/latest/user/agit-support/.
Ah yes, I'm sure the remote being called "origin" is what confuses people when they have to push to a refspec with push options. That's so much more straightforward than a button "create pull request".
As far as I'm concerned the problem isn't that one is easier than the other.
It's that in the github case it completely routes around the git client.
With AGit+gitea or forgejo you can either click your "create pull request" button,
or make a pull request right from the git client. One is necessarily going to require more information than the other to reach the destination...
It's like arguing that instead of having salad or fries on the menu with your entree they should only serve fries.
agreed, you'd need a second name anyway. and probably "origin" and "upstream" is nicer than "github" and "my-fork" because.. the convention seems like it should apply to all the other git hosts too: codeberg, sourcehut, tfs, etc
Git was always explicitly a decentralized, "peer to peer" version control system, as opposed to centralized ones like SVN, with nothing in the protocol itself that makes a distinction between a "server" and a "client". Using it in a centralized fashion is just a workflow that you choose to use (or, realistically, one that somebody else chose for you). Any clone of a repository can be a remote to any other clone, and you can easily have a "git server" (ie. just another directory) in your local filesystem, which is a perfectly reasonable workflow in some cases.
I have a use case just for this. Sometimes my internet goes down while I'm working on my desktop computer. I'll put my work in a branch and push it to my laptop, then go to a coffee shop to continue my work.
There was a thread not to long ago where people were conflating git with GitHub. Git is an incredible tool (after coming from SVN/CVS/p4/source safe) that stands on its own apart from hosting providers.
And GitHub naturally has done nothing to disabuse people of the interpretation that git = GitHub. Meanwhile, the actual raison d'etre for the existence of git of course doesn't use GitHub, or the "pull request" based workflow that GitHub invented and is also not anything intrinsic to git in any way.
It's a little more complex than that. Yes git can work in a peer-to-peer fashion, but the porcelain is definitely set up for a hub-and-spoke model, given how cloning a remote repo only gives you a partial copy of the remote history.
There's other stuff too, like git submodules can't be configured to reference another branch on the local repository and then be cloned correctly, only another remote.
> given how cloning a remote repo only gives you a partial copy of the remote history
When you clone you get the full remote history and all remote branches (by default). That’s painfully true when you have a repo with large binary blobs (and the reason git-lfs and others exist).
> given how cloning a remote repo only gives you a partial copy of the remote history
You may be thinking of the optional -depth switch, which allows you to create shallow clones that don't have the full history. If you don't include that, you'll get the full history when cloning.
I'd say git submodules have such an awkward UX that should probably not be used except in very rare and organized cases. I've done it before but it has to be worth it.
I've been using git since 2007, this only dawned on me last year.
Git is especially prone to the sort of confusion where all the experts you know use it in slightly different ways so the culture is to just wing it until you're your own unique kind of wizard who can't tie his shoes because he favors sandals anyhow.
I like this comment. Over the years I've always found that whenever I see others using git, everyone uses it in different way and even for different purposes. This has left me really confused about what is the standard practice of Git exactly.
This is because people have different needs, Git is trying to cover too many things, there are multiple ways to achieve goals and therefore there is no standard practice. There is no single, standard way to cook chicken breast and that is a way simpler thing.
The solution is to set team/department standards inside companies or use whatever you need as a single contributor. I saw attempts to standardize across a company that is quite decentralized and it failed every time.
> there are multiple ways to achieve goals and therefore there is no standard practice
This is ultimately where, and why, github succeeded. It's not that it was free for open source. It's that it ironed out lots of kinks in a common group flow.
Git is a cultural miracle, and maybe it wouldn't have got its early traction if it had been overly prescriptive or proscriptive, but more focus on those workflows earlier on would have changed history.
This sort of thing is part of the problem. If it takes reading such a long manual to understand how to properly use Git, it's no wonder everyone's workflow is different.
With previous version-control systems, such as SVN and CVS, I found that pair programming helps a great deal with this problem. I started using Git after my last pair-programming gig, unfortunately, but I imagine it would help there too.
(I started using Git in 02009, with networking strictly over ssh and, for pulls, HTTP.)
> all the experts you know use it in slightly different ways
What? Knowing that a git repo is just a folder is nowhere near "expert" level. That's basic knowledge, just like knowing that the commits are nodes of a DAG. Sadly, most git users have no idea how the tool works. It's a strange situation, it'd be like if a majority of drivers didn't know how to change gears.
My point is only that the understanding is uneven. I'm ready to debate the merits of subtrees vs submodules but I didn't know the folder thing. Am I weird? Yes, but here is a place where weird is commonplace.
"Expert level knowledge" implies something more to me than simply few people knowing about it. It's ridiculous to say that knowing how to change gears makes you an expert driver, even if a minority know how to do it (such as in the US e.g.)
In the past I've blown coworkers minds during github outages when I just pulled code from a co-worker's machine and kept working
With remote, if your company stubbornly refuses to use a modern vpn like tailscale, and you can't really network between two computers easily, git format patch and git am, coupled with something like slack messages, works well enough, albeit moderately cumbersome
Yes. I've been subject to claims that a single person can't start a project unless and until an official, centralized repo is setup for them. I've responded with "git init is all that is necessary to get started", but they wouldn't hear it.
Depends, what's the reasoning? Because technically anyone can start a project even without Git. Or even without a computer. Someone can use a pen to write code on a paper.
Depends on what you mean by "a project". If it's policy related, maybe it's company's policy that all code that is written must be stored in a certain way for multitude of reasons.
They don't have a reason. There's no policy that keeps them from doing this. Sure, the whole point is to ultimately have the code in a common place where backups and code review can happen, but if it's a matter of starting something sooner because it takes a few days for the request to flow through to get things set up, they are not constrained by that AT ALL. They can create a git repo with git init immediately, start working, and once the repo is set up in the common area, git push all their work into it. Rather than train people on this, we spend time trying to hasten the common area repo setup time and put additional unneeded burden on the team responsible for that.
You must work at Microsoft? A pound of paperwork for every new repo really shuts down experimental side projects. I showed my colleagues that we can share code via ssh or (painfully) one-drive anytime instead. They reacted like I was asking them to smoke crack behind the dumpsters. “That’s dangerous, gonna get in trouble, no way bro”
Please, elaborate. I can share my screen with coworkers and talk about all sorts of confidential things, and I can even give them full remote access to control everything if I wished. So why would pushing a some plain text code directly to their machine be so fundamentally different than all the other means of passing bits between our machines?
If you share screen you are in control of what you show, if you give someone SSH access, what would stop them from passing/running a small script to fetch everything you have or doing w/e with your computer? I mean it's a blatant security violation to me. Just no reason to do that.
In large corps you usually have policies to not leave your laptop unattended logged in, in the office, that would be potentially even worse than that.
I don't think it has anything to do with being old, this is what happens when your software gets too complex that nobody even knows the very basics. This is highlighted with the documentation, if the software's documentation becomes lengthy enough that it could be an entire book, you're going to be getting these sorts of articles from time to time. Another highlight is bash, that is a huge man page for what should be a shell.
I haven't tried it, but I think it's fine if only one person has write access to any given clone. You can pull back and forth between clones freely. It's if you have two Git clients trying to write to the same repo that you'll have problems.
Shared write access to the same git repo directory can be done sanely, but you have to get a number of things right (same group for all users, everything group writable, sticky bit on directories, set config core.sharedRepository=group): https://stackoverflow.com/a/29646155
Yes, when you're not on NFS. Maybe it works on NFS but I wouldn't bet my project on it. Fortunately at least with Git it's easy to have lots of backups.
If somebody asked me if it's possible to scp my git repo over to another box and use it there or vice versa, I would have said, yes, that is possible. Although I would've felt uneasy doing that.
If somebody asked me if git clone ssh:// ... would definitely work, I wouldn't have known out of the gate, although I would have thought it would be neat if it did and maybe it does. I may have thought that maybe there must be some sort of git server process running that would handle it, although it's plausible that it would be possible to just do a script that would handle it from the client side.
And finally, I would've never thought really to necessarily try it out like that, since I've always been using Github, Bitbucket, etc. I have thought of those as permanent, while any boxes I have could be temporary, so not a place where I'd want to store something as important to be under source control.
You’ve always used GitHub but never known it could work over ssh? Isn’t it the default method of cloning when you’re signed in and working on your own repository…?
I have used SSH for GitHub of course, but the thought that I could also use it from any random machine to machine never occurred to me. And when it might occur to me, I would have thought that maybe SSH is used as a mechanism for authentication, but it might still require some further specialized server due to some unknown protocols of mine. I always thought of SSH or HTTPS as means of authentication and talking to the git server rather than the thing that processes cloning.
E.g. maybe the host would have to have something like apt install git-server installed there for it to work. Maybe it wouldn't be available by default.
I do know however that all info required for git in general is available in the directory itself.
IT support and cybersecurity teams responsible for blocking and enforcing network access restriction to "github.com" ... blocked a user request to install "git" locally citing the former policy. The organization in question does IT services, software development, and maintenance as their main business.
There's an interview with Torvalds where he states that his daughter told him that in the computer lab at her college Linus is more known for Git than Linux
Even someone who knows that git isn't GitHub might not be aware that ssh is enough to use git remotely. That's actually the case for me! I'm a HUGE fan of git, I mildly dislike GitHub, and I never knew that ssh was enough to push to a remote repo. Like, how does it even work, I don't need a server? I suspect this is due to my poor understanding of ssh, not my poor understand of git.
Git is distributed, meaning every copy is isolated and does not depends on other's copy. Adding remotes to an instance is mostly giving a name to an URL(URI?) for the fetch, pull, push operation, which exchange commits. As Commits are immutable and forms a chain, it's easy to know when two nodes diverge and conflict resolution can take place.
From the git-fetch(1) manual page:
> Git supports ssh, git, http, and https protocols (in addition, ftp and ftps can be used for fetching, but this is inefficient and deprecated; do not use them).
You only need access to the other node repo information. There's no server. You can also use a simple path and store the other repo on drive.
Doable. It would basically be ssh but without encryption. You'd have to bang out login by hand, but "username\npassword\n" will probably work, might need a sleep inbetween, and of course you'll have to detect successful login too. Oh, and every 0xff byte will have to be escaped with another 0xff
At that point, may as well support raw serial too.
Supporting rlogin on the other hand is probably as simple as GIT_SSH=rlogin
The server is git itself, it contains two commands called git-receive-pack and git-upload-pack that it starts through ssh and communicate through stdin/out
You can think of the ssh://server/folder as a normal /folder. ssh provides auth and encryption to a remote hosted folder but you can forget about it for the purpose of understanding the nature of git model.
SSH is just a transport to get access to the repo information. The particular implementation does not matter (I think). Its configuration is orthogonal to git.
You do, an SSH server needs to be running on the remote if you want to ssh into it, using your ssh client - the `ssh` command on your laptop. It's just not a http server is all.
You start that server using the `sshd` [systemd] service. On VPSs it's enabled by default.
Git supports both http and ssh as the "transport method". So, you can use either. Browsers OTOH only support http.
Edit: hey this is really exciting. For a long time one of the reasons I've loved git (not GitHub) is the elegance of being a piece of software which is decentralized and actually works well. But I'd never actually used the decentralized aspect of it, I've always had a local repo and then defaulted to use GitHub, bitbucket or whatever instead, because I always thought I'd need to install some "git daemon" in order to achieve this and I couldn't be bothered. But now, this is so much more powerful. Linus Torvalds best programmer alive, change my mind.
BTW, a nice example of this general concept is Emacs' TRAMP mode. This is a mode where you can open and manipulate files (and other things) on remote systems simply by typing a remote path in Emacs. Emacs will then simply run ssh/scp to expose or modify the contents of those files, and of course to run any required commands, such as deleting a file.
I mean, you do need an ssh server. Basically ssh can run commands on the remote machine. Most commonly the command would be a shell, but it can also be git commands.
I always found these sort of categorical denigrations to be off base. If most people do think git = github then that's because they were taught it by somebody. A lot of somebodies for "most people". Likely by the same somebodies who also come to places like this. It has always taken a village to raise a child and that is just as true for an infant as a junior programmer. But instead we live in a sad world of "why didn't schools teach person x"
Despite your indignation, the observation that most people think GitHub is git is entirely true. Do you point it out when you spot someone having that mistaken belief? I do.
I didn’t know either - or rather, I had never stopped to consider what a server needs to do to expose a git repo.
But more importantly, I’m not sure why I would want to deploy something by pushing changes to the server. In my mental model the repo contains the SOT, and whatever’s running on the server is ephemeral, so I don’t want to mix those two things.
I guess it’s more comfortable than scp-ing individual files for a hotfix, but how does this beat pushing to the SOT, sshing into the server and pulling changes from there?
There's a lot of configuration possible due to the fact that git is decentralized. I have a copy on my computer which is where I do work. Another on a vps for backup. Then one on the app server which only tracks the `prod` branch. The latter is actually bare, but there's a worktree for the app itself. The worktree is updated via a post-receive hook and I deploy change via a simple `git push server prod`
You actually led me into a dive to learn what worktrees are, how bare repos + worktrees behave differently from a regular clone and how a repo behaves when it’s at the receiving end of a push, so thanks for that!
I’ve never worked with decentralized repos, patches and the like. I think it’s a good moment to grab a book and relearn git beyond shallow usage - and I suspect its interface is a bit too leaky to grok it without understanding the way it works under the hood.
I actually realized this last week, and have yet to try it. Programming for almost fifty years, using Git for thirteen years, and not an idiot (although there are those who would dispute this, including at times my spouse).
It's not "so easy to use without understanding it", it's the opposite it has so much unnecessary complexity (on top of a brilliant simple idea btw), that once people learn how to do what they need, they stop trying to learn any more from the pile of weirdness that is git.
Decades from now, git will be looked back at in a similar but worse version of the way SQL often is -- a terrible interface over a wonderful idea.
I don't think that's true. In my experience it takes time, but once it clicks, it clicks. Sure, there is a bunch of weirdness in there as well, but that starts way further than where your typical git user stops.
I don't think git would end up this popular if it didn't allow to be used in a basic way by just memorizing a few commands without having to understand its repository model (however simple) well.
What are some fun/creative ways to do GitHub/GitLab style CI/CD with this method? Some kind of entry point script on push that determines what to do next? How could you decide some kind of variables like what the push was for?
Check the docs for the post-receive hook, it does give everything you need. I don't know what you have in mind by "GitHub/Gitlab style", but it's just a shell script, and you can add in as much yaml as you want to feel good about it.
I never thought about it. If somebody had asked me, yeah. Of course it makes sense. But it's just one of those things where I haven't thought about possibility.
I have encountered it in real life many times. These days I try to give jr's extra space to expose their gaps in things I previously assumed were baseline fundamentals - directories and files, tgz/zip files, etc
I imagine larger part of the developer community does not, in fact, know that GitHub is not git and one can get everything they need without feeding their code to Microsoft's AI empire. Just another "Embrace, extend, and extinguish"
I was aware that it should be possible to interact directly with another repository on another machine (or, heck, in another directory on the same machine), which implies that ssh access is sufficient, but I was unaware of how that would be done.
There's definitely generational loss about the capabilities of git. In the beginning, git was a new version control option for people to explore, now git is the thing you learn to collaborate on github/lab/ea. I remember the Chagon book coming out as the peak between dense technical explainers and paint by numbers how-tos.
You can of course also run a local site generator here as well, although for dev3 I took a lighter-weight approach — I just checked in the HEADER.html file that Apache FancyIndexing defaults to including above the file directory listing and tweaked some content-types in the .htaccess file.
This could still fail to update the checkout if it has local changes, but only if they create a merge conflict, and it won't fail to update the bare repo, which is probably what your other checkouts are cloned from and therefore where they'll be pulling from.
regarding that post-update script, can you explain?
I would think you'd want to
cd /home/kragen/public_html/sw/dev3
git update-server-info
git pull
..in that order.
And I wouldn't think you'd need to run git update-server-info again, after git pull. My understanding isthe update-server-info makes updates to info/refs , which is necessary _after a push_.
Cannot emphasize this whole notion enough; Very roughly, Github is to git what gmail is to email.
It's mostly probably fine if that's the thing most of everybody wants to use and it works well; but also it's very unwise to forget that the point was NEVER to have a deeply centralized thing -- and that idea is BUILT into the very structure of all of it.
This reminded me of another discussion on HN a few months ago. Wherein I was reflecting on how the entire culture of internet standards has changed over time:
"In the 80s and 90s (and before), it was mainly academics working in the public interest, and hobbyist hackers. Think Tim Berners-Lee, Vint Cerf, IETF for web/internet standards, or Dave Winer with RSS. In the 00s onward, it was well-funded corporations and the engineers who worked for them. Think Google. So from the IETF, you have the email protocol standards, with the assumption everyone will run their own servers. But from Google, you get Gmail.
[The web] created a whole new mechanism for user comfort with proprietary fully-hosted software, e.g. Google Docs. This also sidelined many of the efforts to keep user-facing software open source. Such that even among the users who would be most receptive to a push for open protocols and open source software, you have strange compromises like GitHub: a platform that is built atop an open source piece of desktop software (git) and an open source storage format meant to be decentralized (git repo), but which is nonetheless 100% proprietary and centralized (e.g. GitHub.com repo hosting and GitHub Issues)."
From: https://news.ycombinator.com/item?id=42760298
Yes. And honestly though, this is the sort of thing that makes me generally proclaim that Free Software and Open Source won.
It was extremely unlikely that it would be some kind of free utopia; but also, it's extremely remarkable what we've been able to keep generally free, or at least with a free-enough option.
Idk if git was designed to not be used in a centralized way. Like all other common CLIs, it was simply designed to work on your PC or server without caring who you are, and nothing stopped a corp from turning it into a product. Torvalds made git and Linux, then he put Linux on Github.
> This is a great way to [...] work on server-side files without laggy typing or manual copying
This is the usecase mentioned in the article and it wouldn't work with a bare repo. But if the server your SSH'ing to is just a central point to sync code across machines, then you're right: multiple hoops mentioned in the article are solved by having the central repo bare.
FWIW a single user working on a remote versioned directory is indeed a reasonable use-case for receive.denyCurrentBranch=updateInstead, but IMO the article should have made it clear that it's not necessarily a good choice in general.
My favorite git trick is using etckeeper & git subtree to manage multiple machines from a single repo . A single git repo can “fan out” to dozens of instances . It’s useful even for “managed” hosts with terraform because etckeeper snapshots config with every change, catching bugs in the terraform config.
During the dev / compile / test flow, git makes a lightweight CI that reduces the exposure to your primary repo . Just run `watch -n 60 make` on the target and push using `git push` . The target can run builds without having any access to your primary (GitHub) repo.
The more I use git, the more I discover more depth to it.
So many features and concepts; it's easy to think you understand the basics, but you need to dig deep into it's origin and rationale to begin to grasp the way of thinking it is built around.
And the API surface area is much larger than one would think, like an iceberg
So I find it really weirdly low level in a way. Probably what is needed is is a higher-level CLI to use it in the most sensible, default way, because certainly the mental model most people use it with is inadequate.
If you want a public facing "read only" ui to public repositories you can use cgit (https://git.zx2c4.com/cgit/about/) to expose them. That will enable others to git clone without using ssh.
I keep my private repositories private and expose a few public ones using cgit.
And it didn’t work. You have to ssh to the remote server and “git init” on a path first. How uncivilized.
Bitkeeper and a few other contemporaries would let you just push to a remote path that doesn’t exist yet and it’d create it. Maybe git added this since then, but at the time it seemed like a huge omission to me.
Hah, you made me check whether clone's second argument can be a URL. But no, it's explicitly "<directory>", so it can't be used as a equivalent of "git push --mirror" :)
I suspect many who always use git remotely don't know that you can easily work with local repositories as well using the file protocol, git clone file:///path/to/repository will create a clone of the repository at the path.
I used that all the time when I had to move private repositories back and forth from work, without ssh access.
> It’s also backed up by default: If the server breaks, I’ve still got the copy on my laptop, and if my laptop breaks, I can download everything from the server.
This is true, but I do also like having backups that are entirely decoupled from my own infrastructure. GitHub personal private accounts are free and I believe they store your data redundantly in more than one region.
I imagine there's a way to setup a hook on your own server such that any pushes are then pushed to a GitHub copy without you having to do anything else yourself.
Git post-update hooks to do deployment FTW. I looked into the whole push-to-github to kick off CI and deployment; but someone mentioned the idea of pushing over ssh to a repo on your server and having a post-update hook do the deployment, and that turned out to be much simpler.
As a git user "not by choice" (my preference going for mercurial every single day), I never understood why git needs this distinction between bare/non-bare (or commit vs staging for that matter). Seems like yet another leaky abstraction/bad design choice.
A repo is as database containing a tree of commits. Then you got the concept of branch, which points to a specific commit. Then there's the special pointer HEAD which is the latest commit for the current worktree.
When you checkout (now switch) a branch, HEAD is now the same as the branch (they point to the same commit). When you do operation like commit, reset, reset,... both the head and the branch are updated. So if a remote node tries to update the local node via a push on its end, that would mess up the local worktree. So you create a bare repo instead which can't contain a local worktree.
Note: A worktree is computed from the initial commit to the commit currently identified by HEAD by following the parent information on each commit.
The staging area is like a stored snapshot of what you would like to commit. You can always create patch between HEAD and the worktree, edit it, and then save the patch as the commit, then apply the leftover to the worktree. The staging just make that easier. It's a WIP patch for the next commit.
Mercurial has no distinction between a bare repo and a non-bare repo: any repo can have a working copy or not. You can check out a working copy with `hg update somerevision`, or get rid of it with `hg update null`.
You can push to a repo with a working copy, if you like; nothing will happen to that working copy unless you run `hg update`. Since you don’t need a working copy on the server’s repo, you never run `hg update` on it, and it’s effectively what git calls a bare repository.
> When you checkout (now switch) a branch, HEAD is now the same as the branch (they point to the same commit).
Actually, HEAD now points to that branch, which in turn points to the commit. It's a different state than when HEAD points directly to the same commit (called "detached HEAD" in Git's terminology) where this issue doesn't happen as you're not on a branch at all. It's a subtle, but important distinction when trying to understand what happens under the hood there.
So, exactly as DrinkyBird said: I still don't see a good reason for this distinction to exist, what's in the repo's history and in its working directory are orthogonal concepts that are tied together by a bad UX for no apparent gain.
Staging is immensely useful in more than one case.
Case one: WiP on a branch, code is pretty stable, but I want to do some experiments which will likely be deleted. I stage everything and then make (unstaged) changes which I can then undo with two keystrokes.
Case two: I'm reviewing a complex PR, so I first merge it with --no-commit, then unstage everything and then stage chunks (or even individual lines) I have already reviewed.
Case three: I was coding in the state of flow and now I have a lot of changes I want to commit, but I want to separate them into several atomic commits. I stage the first batch of changes, commit, then stage another, commit, etc.
There are probably more, but these three alone are worth having the staging area.
Case one: you don't need staging. You can stash, or just commit and checkout HEAD^
Case two: you don't need staging. You can stash, and then unstash incrementally (I would be shocked if git doesn't have the equivalent of `hg unshelve --interactive` and its keyboard friendly TUI)
Case three: you don't need staging. You can just edit/amend the series (rebase --interactive I believe you guys call that).
That is to say, all that you want to put in your stash, you could commit directly to the DAG, and edit to your convenience, with the regular history-rewriting tools already at your disposal. And the off-DAG stuff can be handled by stash (and even there, a normal commit that you would rebase to its destination would perfectly do).
And what I described is incidentally what https://github.com/jj-vcs/jj does, which can be pretty-well described as "taking the best of all major VCSes"
Though I wasn't trying to say that there is no need for staging-based workflows,
I was just saying that there is nothing in terms of convenience or capabilities that the staging area does that can't be achieved with just regular commits and amending/rewriting.
The immediate response from many git users when confronted to alternative VCSes is "well, it doesn't have a staging area, so it's obviously inferior" instead of going with "let's see how differently they approach this problem, and perhaps I will like it/git isn't all perfect after all".
Instead of excluding non-public directories, I like to make an explicit `public` directory (or `doc`, `doc-root`, whatever you want to call it). Then configure your server to point to that subdirectory and don’t worry about the repo.
I usually throw `etc` and `log` directories at the top level as well and out my server config in etc, and have a gitignite rule to ignore everything in logs, but it’s there and ready for painless deployment.
Since the web root is already a sub directory, more sensitive things can go into the same repo without worrying about exposing them.
I expose the .git directories on my web server and never considered it a problem. I also expose them on GitHub and didn't consider that a problem either...
Super common failure is accidental commit of a secret key. People suck at actually deleting something from git history. Had one colleague leak a Digital Ocean key this way with an accidental env file commit. He reverted, but the key is of course still present in the project history.
The speed at which an accidentally committed and reverted key is compromised and used to say launch a fleet of stolen VPSes on a github public repo nowadays is incredible. Fortunately most of the time your provider will cancel the charges...
This has always been the roughest part of git for me, the process to remove accidentally committed sensitive content. Sure we should all strive not to commit stupid things in the first place, and of course we have tools like gitignore, but we are all only human.
"Sensitive data can be removed from the history of a repository if you can carefully coordinate with everyone who has cloned it and you are willing to manage the side effects."
Back when I started at my current job... 15 years ago... We had no central git server. No PR workflow. We just git pull-ed from each others machines. It worked better than you would expect.
We then went to using a central bare repo on a shared server, to hosted gitlab(? I think - it was Ruby and broke constantly) eventually landing on GitHub
This is classic git usage. A "pull request" was literally just asking someone to pull from your branch. GitHub co-opted the term for their own thing.
The thing that people really don't seem to get these days is how your master branch is a different branch from someone else's master branch. So pulling from one master to another was a normal thing. When you clone you get a copy of all the branches. You can commit to your master branch all you want, it's yours to use however you want to.
There was a brief period when Google Cloud had support for hosting git on a pay-per-use basis. (I think it was called Google Cloud Repositories.) It had a clunky but usable UI.
I really preferred the idea of just paying for what I used -- rather than being on a "freemium" model with GitHub.
But -- as many things with Google -- it was shutdown. Probably because most other people do prefer the freemium model.
I wonder if this kind of thing will come back in style someday, or if we are stuck with freemium/pro "tiers" for everything.
(Use `git pull`? If the different people push to different branches, then there's no conflict and no problem. If you try to push different things into the same branch, the second person will get told their branch is out of date. They can either rebase or - if this is allowed by the repo config - force push over the previous changes...)
To my knowledge git-lfs is only really designed to store your large files on a central server. I think it also uses its own out-of-band (from the perspective of git) protocol and connection to talk to that server. So it doesn't work with a standard ssh remote, and breaks git's distributed nature.
For an actually distributed large file tracking system on top of git you could take a look at git-annex. It works with standard ssh remotes as long as git-annex is installed on the remote too (it provides its own git-annex-shell instead of git-shell), and has a bunch of additional awesome features.
Yes exactly, creating git user on Linux machine and configuring it just for git turned out to be easiest way how to get Source Tree and Git in Windows work with it out of the box.
This is definitely nice but it doesn’t really support the full range of features of Git, because for example submodules cannot be local references. It’s really just easier to set up gitolite and use that in almost the same exact way but it’s much better.
What is it with code on blog posts where fonts have uneven size and/or font types (e.g. italics mixed in with regular)? I see this from time to time and I wonder if it’s intentional.
One note, xcode and maybe some other clients can't use http "dumb mode". Smart mode is not hard to set up, but it's a few lines of server config more than this hook.
TIL about the update options for checked out branch. In practise though usually you want just the .git "bare" folder on server
That's because git is hard to use and full of commands which are making no sense. Eventually people will learn to just clone, pull, push and occasionally merge and be done with it.
People said the same thing about “advanced” operations with cvs and svn (and just called their admin for p4 or source safe). But I really don’t understand the sentiment.
Managing code is one of the cornerstones of software engineering. It would be like refusing to learn how to use a screwdriver because someone really just wants to hammer things together.
The great thing about $your-favorite-scm is that it transcends language or framework choices and is fungible for early any project, even outside of software. I’m surprised it isn’t part of more professional tools.
> Managing code is one of the cornerstones of software engineering. It would be like refusing to learn how to use a screwdriver because someone really just wants to hammer things together.
Ok, then make the commands make sense. For example 90%+ people has no idea what rebase does, yet it is a useful command.
People does not want to learn with git outside of what works, because they can't experiment. The moment they will "hold it wrong" whole repo will break into pieces, unable to go forward or backwards. Hopefully they did not commit.
Git feels like a hammer covered in razor blades. The moment you will try to hold it differently you will cut yourself and somebody else will need to stich you up.
Most people would just use `app` `app (final)`, `app (final 2)`, etc... VCS exists for a reason and I strongly believe that the intersection of people that say git is hard and people that do not know why you want a VCS is nearly a perfect circle.
If you think the bare bones example is interesting and want something simple just for you or a small group of people, this is one step up. There's no web interface. The admin is a git repository that stores ssh public keys and a config file that defines repo names with an ACL. When you push, it updates the authorization and inits new repositories that you name.
I put everything in repos at home and a have multiple systems (because of VMs) so this cleaned things up for me considerably.
I really like forgejo, but the git hosting bit is really just one feature for me. Their ci/cd runners, package repos and such are all things I need and forgejo includes in one nice bundle.
If I was just using it for git hosting I'd probably go for something more light weight to be honest.
A lot of people do host Forejo but unless you are actually working with other people and they need a reduction in access via pull requests it doesn't do much other than provide a pretty GUI to look at. The bare SSH approach makes more sense for personal projects.
Git is distributed, so there's no least power and all that. Everyone has full power over their own copy. What you want is one copy being the source of truth. You can always use HTTP for read-only access to that copy with a limited set of people having write access to update the copy. Patches can be shared via anything (git has built-in support for email).
The proper way to do this to make a "bare" clone on the server (a clone without a checked out branch). I was doing this in 2010 before I even signed up to GitHub.
I do something similar. I create a bare repo on my dropbox folder or nas mount. Then checkout from bare repo file path to some place where I will be doing all the work.
Perhaps the only issue with this setup is that you lose some of the robustness of git: mess up one repo beoynd repair, and you've just messed up all the checkouts everywhere.
I sync my repos manually (using GitHub as the always-on remote, but I'm not particularly attached to it). This gives me more resilience should I blow up the repo completely (hard to do, I know).
this article is very bad advice. this way things are extremely brittle and there's a reason all those settings are disabled by default. you will lose data, save from very specific use cases
the vastly superior way is 'git bare' which is a first class supported command without hacky settings.
> I tried this and it is never as smooth as described.
I think your comment shows some confusion that it's either the result or cause of some negative experiences.
Starting with GitHub. The primary reason it "just works" is because GitHub, like any SaaS offering, is taking care of basic things like managing servers, authorization, access control, etc.
Obviously, if you have to setup your own ssh server, things won't be as streamlined as clicking a button.
But that's obviously not the point of this post.
The point is that the work you need to do to setup a Git server is way less than you might expect because you already have most of the things already set, and the ones that aren't are actually low-hanging fruit.
This should not come as a surprise. Git was designed as a distributed version control system. Being able to easily setup a stand-alone repository was a design goal. This blog post covers providing access through ssh, but you can also create repositories in any mount point of your file system, including in USB pens.
And, yes, "it just works".
> The official Git documentation for example has its own documentation that I failed to get work. (it is vastly different from what OP is suggesting)
I'm sorry, the inability to go through the how-to guide that you cited has nothing to do with Git. The guide only does three things: create a user account, setup ssh access to that account, and create a Git repository. If you fail to create a user account and setup ssh, your problems are not related to Git. If you created a user account and successfully setup ssh access, all that is missing is checking out the repo/adding a remote repo. If you struggle with this step, your issues are not related to Git.
It's obvious as soon as you consider that your push will overwrite a ref that's currently checked out in the target's repo workdir. The exact same thing happens when pushing to local repos. You don't have to make a repo bare to avoid this issue, but it's certainly the easiest way to avoid it altogether when you don't need a workdir on the server side.
It's obvious that it needs to update the ref. It's not obvious that this would cause any problems. You could fix HEAD as part of writing the ref. Automatically managing HEAD is normal git behavior.
It's obvious that something non-obvious would have to happen with the workdir behind the user's back. Imagine that you are working with your workdir while someone else pushes something to your repo. Bailing out is the only sane option (unless something else has been explicitly requested by the user).
...except of all the things that rely on the HEAD pointing to another ref now changing their behavior. gbp will by default bail off if HEAD is not on a branch, "git commit" won't update the ref you thought it will cause you're now suddenly on "detached HEAD" etc.
I've never heard of... debian package builder? I don't care if it gets annoyed; if that's one of the biggest issues then that's a good sign for the method.
Yes the commit won't be on the branch you want, but you'd get about the same issue if the two repos had a bare upstream. The branch diverges and you need to merge. It's a bit less ergonomic here but could be improved. Git could use branch following improvements in general.
> Yes the commit won't be on the branch you want, but you'd get about the same issue if the two repos had a bare upstream.
Not at all. The commit would have "landed" on the exact branch you thought it will. How it will be reconciled with a diverged remote branch is completely orthogonal and may not even be of concern in some use cases at all.
The situation is almost identical except you don't have a cute name for your new commit. Let's say you add a ref to your detached commit, perhaps local/foo. Then you're looking at a divergence between foo and local/foo. If you had a bare upstream it would be a divergence between origin/foo and foo. No real difference. And if you don't want to reconcile then you don't have to.
If git was a tiny bit smarter it could remember you were working on "foo" even after the ref changes.
Of course it could, but that doesn't yet mean it should. A checked-out ref is considered to be in-use and not to be manipulated (unless done in tandem with HEAD), not just by "git push" but also other tools like "git branch". It's consistent and, IMO, less surprising than what you propose. It could be an optional behavior configured by receive.denyCurrentBranch, though I don't see a good use-case for it that isn't already handled by updateInstead.
If you use "git branch -d" you should expect the ref to be deleted, and yet:
> error: cannot delete branch 'main' used by worktree at '/tmp/git'
You could build the system differently and what seems like a sane default would be different there, but it would be a different system. In this system, HEAD isn't being manipulated by things not meant to manipulate it.
Yeah this is the best arguments for GitHub type of web git GUI. Not knowing bare repo seems just like a devs not reading docs. And I'm sorry in this day and age devs needs to keep up and just type git like curl http://...../install.sh type of thing.
However would NEVER trust Github since the MS acquisition. codeberg and https://forgejo.org are perfectly sound FOSS alternative to GitHub and GigLabs nowdays.
The vast majority of developers working with git daily don’t know what a bare repo is, or that it exists at all. It’s not obscure knowledge as such, it’s just never come up for them as something they need.
The vast majority [0] of developers working with git daily have no mental model of git repos and just do a mental equivalent of copy'n'pasting commands and it's enough to let them do their work (until something breaks at least), so it doesn't seem like a particularly good indicator of whether something is obscure or not. There are many obscure things hiding in git, bare repos aren't one of those :)
The cool thing is that once you know how simple it is to self host (I certainly didn't know before, just used github), you learn a skill that you can apply to many different contexts, and understand better what actually goes on in systems you depend on. That's what these "tech should be invisible" people miss, where they tout that you should instead learn SASS solutions where you have zero ownership nor agency, instead of taking the time to learn transferable skills.
The knowledge is neither obscure nor tribal, it is public and accessible. And likely already on your system, in the form of man-pages shipped with your git binaries.
> The problem with software development is that not knowing such "tribal knowledge" is considered incompetence.
It is "incompetence," or at the very least, it is unwise.
At the very least, a huge part of the intent of Git's very design was decentralization; though as is the case with many good tools, people don't use them as they are designed.
Going further, simply because "deeply centralized Git" is very popular, does not AT ALL determine that "this is the better way to do things." Please don't frame it as if "popular equals ideal."
I understand where you're coming from, but this seems like a terrible defeatist attitude to have.
What are we supposed to do ... throw our hands up because GitHub won?
I'll be down voted, but I'll say it. If you hold that attitude and you don't learn the fundamentals, if you don't understand your tools, you're a bad developer and a poor craftsman. You're not someone I would hire or work with.
git is not "the fundamentals". It's a tool that's very difficult to learn but we are forced to use because "it won" at some point.
Git's difficulty is NOT intrinsic; it could be a much better tool if Torvalds were better at UX. In short, I don't blame people who don't want to "learn git". They shouldn't have to learn it anymore than one learns to use a browser or Google docs.
For normal users. Having this tribal knowledge is basically what makes developer and it’s their job to make technology invisible for others. Someone has to be behind the curtain.
> Why is GitHub popular? its not because people are "dumb" as others think.
> Its because GitHub "Just Works".
Git also "just works". GitHub simply offers a higher level of abstraction, a graphical UI, and some value-add features on top of Git. How much better all this really is arguable. I would say that it's disastrous that most developers rely on a centralized service to use a distributed version control system. Nevermind the fact that the service is the single largest repository of open source software, owned and controlled by a giant corporation which has historically been hostile to OSS.
GitHub "won" because it came around at the right time, had "Git" in its name—which has been a perpetual cause of confusion w.r.t. its relation with Git—, and boosted by the success of Git itself largely due to the cult of personality around Linus Torvalds. Not because Git was technically superior, or because GitHub "just works".
> You don't need obscure tribal knowledge
As others have said, a bare repository is certainly not "tribal knowledge". Not anymore than knowing how to use basic Git features.
> Like the adge goes, "Technology is best when it is invisible"
Eh, all technology is an abstraction layer built on top of other technology. Whether it's "invisible" or not depends on the user, and their comfort level. I would argue that all abstractions also make users "dumber" when it comes to using the layers they abstract. Which is why people who only rely on GitHub lose the ability, or never learn, to use Git properly.
I feel like something was lost along the way.
will give you a git repo without a working set (just the contents typically in the .git directory). This allows you to create things like `foo.git` instead of `foo/.git`.“origin” is also just the default name for the cloned remote. It could be called anything, and you can have as many remotes as you’d like. You can even namespace where you push back to the same remotes by changing fetch and push paths. At one company it was common to push back to `$user/$feature` to avoid polluting the root namespace with personal branches. It was also common to have `backup/$user` for pushing having a backup of an entire local repo.
I often add a hostname namespace when I’m working from multiple hosts and then push between them directly to another instead of going back to a central server.
For a small static site repo that has documents and server config, I have a remote like:
So I can push from my computer directly to that server, but those branches won’t overwrite the server’s branches. It acts like a reverse `git pull`, which can be useful for firewalls and other situations where my laptop wouldn’t be routable.It doesn't include pull requests, when cloning from github, though.
> It doesn't include pull requests, when cloning from github, though.
Because GitHub pull requests are a proprietary, centralized, cloud-dependent reimplementation of `git request-pull`.
How the "free software" world slid head first into a proprietary cloud-based "open source" world still boils my blood. Congrats, Microsoft loves and owns it all, isn't that what what we always wanted?
When this kind of “sliding” happens it’s usually because the base implementation was missing functionality. Turns out CLI interfaces by themselves are (from a usability perspective) incomplete for the kind of collaboration git was designed to facilitate.
In another post discussion, someone suggested git as an alternative to overleaf, a Google Docs for latex... I guess there are plenty of people with blind spots for things that are technically possible, and usabel to experts, and UI that actually empowers much broader classes of users to wield the feature.
If you actually use the live collaboration features of overleaf, sure, it’s not a replacement. But lots of people use overleaf to write latex by themselves. The experience is just so much worse than developing locally and tracking changes with git.
Is the joke that overleaf has decent git integration?
> Turns out CLI interfaces by themselves are (from a usability perspective) incomplete for the kind of collaboration git was designed to facilitate.
git was designed to facilitate the collaboration scheme of the Linux Kernel Mailing List, which is, as you might guess... a mailing list.
Rather than a pull-request (which tries to repurpose git's branching infrastructure to support collaboration), the intended unit of in-the-large contribution / collaboration in git is supposed to be the patch.
The patch contribution workflow is entirely CLI-based... if you use a CLI mail client (like Linus Torvalds did at the time git was designed.)
The core "technology" of this is, on the contributor side:
1. "trailer" fields on commits (for things like `Fixes`, `Link`, `Reported-By`, etc)
2. `git format-patch`, with flags like `--cover-letter` (this is where the thing you'd think of as the "PR description" goes), `--reroll-count`, etc.
3. a codebase-specific script like Linux's `./scripts/get_maintainer.pl`, to parse out (from source-file-embedded headers) the set of people to notify explicitly about the patch — this is analogous to a PR's concept of "Assignees" + "Reviewers"
4. `git send-email`, feeding in the patch-series generated in step 2, and targeting the recipients list from step 3. (This sends out a separate email for each patch in the series, but in such a way that the messages get threaded to appear as a single conversation thread in modern email clients.)
And on the maintainer side:
5. `s ~/patches/patch-foo.mbox` (i.e. a command in a CLI email client like mutt(1), in the context of the patch-series thread, to save the thread to an .mbox file)
6. `git am -3 --scissors ~/patches/patch-foo.mbox` to split the patch-series mbox file back into individual patches, convert them back into an annotated commit-series, and build that into a topic branch for testing and merging.
Subsystem maintainers, meanwhile, didn't use patches to get topic branches "upstream" [= in Linus's git repo]. Linus just had the subsystem maintainers as git-remotes, and then, when nudged, fetched their integration branches, reviewed them, and merged them, with any communication about this occurring informally out-of-band. In other words, the patch flow was for low-trust collaboration, while direct fetch was for high-trust collaboration.
Interestingly, in the LKML context, `git request-pull` is simply a formalization of the high-trust collaboration workflow (specifically, the out-of-band "hey, fetch my branches and review them" nudge email). It's not used for contribution, only integration; and it doesn't really do anything you can't do with an email — its only real advantages are in keeping the history of those requests within the repo itself, and for forcing requests to be specified in terms of exact git refs to prevent any confusion.
It still blows my mind how git has lost it's original ideas of decentralized development because of github and how github, a for-profit - centralized - close-sourced forge, became the center for lots of important open source projects. We need radicle, forgejo, gitea to catch up even more!
Once they killed mercurial on bitbucket, it was over.
They are available as refs on the remote to pull though, they just aren't listed so don't end up mirrored either.
They are listed tho. You can very much see them in info/refs.
My bad! I got misled by grandparent - they are in fact mirrored with "git clone --mirror" as well.
Having a web interface was really appreciated by users, it would seem.
>Having a web interface
It's not the interface, it's the web hosting. People want a free destination server that's up 24/7 to store their repository.
If it was only the web interface, people could locally install GitLab or Gitea to get a web browser UI. (Or use whatever modern IDE code editor to have a GUI instead of a CLI for git commands.) But doing that still doesn't solve what GitHub solves: a public server to host the files, issue tracking, etc.
Before git & Github, people put source code for public access on SourceForge and CodeProject. The reason was the same: a zero-cost way to share code with everybody.
GH is essentially an unlimited storage space. There are countless scripts which makes it possible to even use it as an unlimited mounted storage
It is also other features such as GitHub workflow, releases, integration with other tools, webhooks etc. that makes it useful.
I often init a bare repo on single-use server's I'm working on.
Then, have separate prod and staging clones parallel to that.
Have a post-commit hook set on the bare repo that automatically pushes updates to the staging repo for testing.
When ready, then pull the updates into prod.
Might sound strange, but for certain clients hosting situations, I've found it allows for faster iterations. ymmv
> “origin” is also just the default name for the cloned remote. It could be called anything, and you can have as many remotes as you’d like.
One remote can also hold more URLs! This is arguably more obscure (Eclipse's EGit doesn't even support it), but works wonders for my workflow, since I want to push to multiple mirrors at the same time.
Whenever I fork a repo I rename origin to “fork” and then add the parent repo as a remote named “upstream” so i can pull from that, rebase any of my own changes in to, and push to fork as needed.
Multiple remotes is also how you can combine multiple repos into one monorepo by just fetching and pulling from each one, maybe into different subdirectories to avoid path collisions.
I always thought it would have been better, and less confusing for newcomers, if GitHub had named the default remote “github”, instead of origin, in the examples.
Is this something the remote can control? I figured it was on the local cloner to decide.
Can’t test it now but wonder if this is changed if it affects the remote name for fresh clones: https://git-scm.com/docs/git-config#Documentation/git-config...
If I clone my fork, I always add the upstream remote straight away. Origin and Upstream could each be github, ambiguous.
GitHub could not name it so, because it's not up to GitHub to choose.
There are places where it does choose, but arguably it makes sense for it to be consistent with what you get when using "git clone".
How is it less confusing when your fork is also on github?
Requiring a fork to open pull requests as an outsider to a project is in itself a idiosyncrasy of GitHub that could be done without. Gitea and Forgejo for example support AGit: https://forgejo.org/docs/latest/user/agit-support/.
Nevertheless, to avoid ambiguity I usually name my personal forks on GitHub gh-<username>.
No, it's a normal feature of Git. If I want you to pull my changes, I need to host those changes somewhere that you can access. If you and I are both just using ssh access to our separate Apache servers, for example, I am going to have to push my changes to a fork on my server before you can pull them.
And of course in Git every clone is a fork.
AGit seems to be a new alternative where apparently you can push a new branch to someone else's repository that you don't normally have access to, but that's never guaranteed to be possible, and is certainly very idiosyncratic.
> Requiring a fork to open pull requests as an outsider to a project is in itself a idiosyncrasy of GitHub that could be done without. Gitea and Forgejo for example support AGit: https://forgejo.org/docs/latest/user/agit-support/.
Ah yes, I'm sure the remote being called "origin" is what confuses people when they have to push to a refspec with push options. That's so much more straightforward than a button "create pull request".
As far as I'm concerned the problem isn't that one is easier than the other. It's that in the github case it completely routes around the git client. With AGit+gitea or forgejo you can either click your "create pull request" button, or make a pull request right from the git client. One is necessarily going to require more information than the other to reach the destination...
It's like arguing that instead of having salad or fries on the menu with your entree they should only serve fries.
agreed, you'd need a second name anyway. and probably "origin" and "upstream" is nicer than "github" and "my-fork" because.. the convention seems like it should apply to all the other git hosts too: codeberg, sourcehut, tfs, etc
Huh. Everyone seems to use "origin" and "upstream". I've been using "origin" and "fork" the whole time.
I use "mine" for my fork.
Git was always explicitly a decentralized, "peer to peer" version control system, as opposed to centralized ones like SVN, with nothing in the protocol itself that makes a distinction between a "server" and a "client". Using it in a centralized fashion is just a workflow that you choose to use (or, realistically, one that somebody else chose for you). Any clone of a repository can be a remote to any other clone, and you can easily have a "git server" (ie. just another directory) in your local filesystem, which is a perfectly reasonable workflow in some cases.
I have a use case just for this. Sometimes my internet goes down while I'm working on my desktop computer. I'll put my work in a branch and push it to my laptop, then go to a coffee shop to continue my work.
When I do this I usually push to a bare repo on a USB pendrive.
This is a better summary than mine.
There was a thread not to long ago where people were conflating git with GitHub. Git is an incredible tool (after coming from SVN/CVS/p4/source safe) that stands on its own apart from hosting providers.
And GitHub naturally has done nothing to disabuse people of the interpretation that git = GitHub. Meanwhile, the actual raison d'etre for the existence of git of course doesn't use GitHub, or the "pull request" based workflow that GitHub invented and is also not anything intrinsic to git in any way.
It's a little more complex than that. Yes git can work in a peer-to-peer fashion, but the porcelain is definitely set up for a hub-and-spoke model, given how cloning a remote repo only gives you a partial copy of the remote history.
There's other stuff too, like git submodules can't be configured to reference another branch on the local repository and then be cloned correctly, only another remote.
> given how cloning a remote repo only gives you a partial copy of the remote history
When you clone you get the full remote history and all remote branches (by default). That’s painfully true when you have a repo with large binary blobs (and the reason git-lfs and others exist).
> given how cloning a remote repo only gives you a partial copy of the remote history
You may be thinking of the optional -depth switch, which allows you to create shallow clones that don't have the full history. If you don't include that, you'll get the full history when cloning.
You only get it actually full with "--mirror" switch, but for most use-cases what you get without it is already "full enough".
I'd say git submodules have such an awkward UX that should probably not be used except in very rare and organized cases. I've done it before but it has to be worth it.
But I get your larger point.
And they're often (not always) used where subtrees would fit better.
Maybe I'm too old, but are there people that really didn't know that any ssh access is sufficient for using git?
I've been using git since 2007, this only dawned on me last year.
Git is especially prone to the sort of confusion where all the experts you know use it in slightly different ways so the culture is to just wing it until you're your own unique kind of wizard who can't tie his shoes because he favors sandals anyhow.
I like this comment. Over the years I've always found that whenever I see others using git, everyone uses it in different way and even for different purposes. This has left me really confused about what is the standard practice of Git exactly.
This is because people have different needs, Git is trying to cover too many things, there are multiple ways to achieve goals and therefore there is no standard practice. There is no single, standard way to cook chicken breast and that is a way simpler thing.
The solution is to set team/department standards inside companies or use whatever you need as a single contributor. I saw attempts to standardize across a company that is quite decentralized and it failed every time.
> there are multiple ways to achieve goals and therefore there is no standard practice
This is ultimately where, and why, github succeeded. It's not that it was free for open source. It's that it ironed out lots of kinks in a common group flow.
Git is a cultural miracle, and maybe it wouldn't have got its early traction if it had been overly prescriptive or proscriptive, but more focus on those workflows earlier on would have changed history.
The Pro Git book is available online for free
https://git-scm.com/book/en/v2
This sort of thing is part of the problem. If it takes reading such a long manual to understand how to properly use Git, it's no wonder everyone's workflow is different.
Do you know any construction folks?
With previous version-control systems, such as SVN and CVS, I found that pair programming helps a great deal with this problem. I started using Git after my last pair-programming gig, unfortunately, but I imagine it would help there too.
(I started using Git in 02009, with networking strictly over ssh and, for pulls, HTTP.)
> all the experts you know use it in slightly different ways
What? Knowing that a git repo is just a folder is nowhere near "expert" level. That's basic knowledge, just like knowing that the commits are nodes of a DAG. Sadly, most git users have no idea how the tool works. It's a strange situation, it'd be like if a majority of drivers didn't know how to change gears.
My point is only that the understanding is uneven. I'm ready to debate the merits of subtrees vs submodules but I didn't know the folder thing. Am I weird? Yes, but here is a place where weird is commonplace.
The majority of drivers DON’T know how to change gears.
You are simultaneously saying that something is not expert level knowledge while acknowledging that most people don’t know it. Strange.
> The majority of drivers DON’T know how to change gears.
I'm not sure that's true, unless you only take certain parts of the world into consideration.
"Expert level knowledge" implies something more to me than simply few people knowing about it. It's ridiculous to say that knowing how to change gears makes you an expert driver, even if a minority know how to do it (such as in the US e.g.)
I think the idea is it shouldn't be expert level. It used to be in every tutorial. But you're right these days it may indeed be expert level knowledge
In the past I've blown coworkers minds during github outages when I just pulled code from a co-worker's machine and kept working
With remote, if your company stubbornly refuses to use a modern vpn like tailscale, and you can't really network between two computers easily, git format patch and git am, coupled with something like slack messages, works well enough, albeit moderately cumbersome
My way used to be in the past, put bare repos on Dropbox, clone the bare repo to a real path. Done.
That way, I
1. didn't have to worry about sync conflicts. Once complete, just push to origin 2. had my code backed up outside my computer
I can't exactly remember, if it saves space. I assumed it does, but not sure anymore. But I feel it was quite reliable.
I gave that way up with GitHub. But thinking of migrating to `Codeberg`
With `tailscale`, I feel we have so much options now, instead of putting our personal computer out on the Internet.
Yes. I've been subject to claims that a single person can't start a project unless and until an official, centralized repo is setup for them. I've responded with "git init is all that is necessary to get started", but they wouldn't hear it.
Depends, what's the reasoning? Because technically anyone can start a project even without Git. Or even without a computer. Someone can use a pen to write code on a paper.
Depends on what you mean by "a project". If it's policy related, maybe it's company's policy that all code that is written must be stored in a certain way for multitude of reasons.
They don't have a reason. There's no policy that keeps them from doing this. Sure, the whole point is to ultimately have the code in a common place where backups and code review can happen, but if it's a matter of starting something sooner because it takes a few days for the request to flow through to get things set up, they are not constrained by that AT ALL. They can create a git repo with git init immediately, start working, and once the repo is set up in the common area, git push all their work into it. Rather than train people on this, we spend time trying to hasten the common area repo setup time and put additional unneeded burden on the team responsible for that.
What are you using for the centralized repos? Why does it take multiple days in the first place?
You are missing the whole point. The OP is mentioning how people are so used to using github, that they are so oblivion on using git offline
It just doesn't make sense to me unless it's a company policy type of thing.
Not even "offline", just "using git".
You must work at Microsoft? A pound of paperwork for every new repo really shuts down experimental side projects. I showed my colleagues that we can share code via ssh or (painfully) one-drive anytime instead. They reacted like I was asking them to smoke crack behind the dumpsters. “That’s dangerous, gonna get in trouble, no way bro”
If you are working in a large corp and not your own side project, that honestly does sound like a bad idea.
Please, elaborate. I can share my screen with coworkers and talk about all sorts of confidential things, and I can even give them full remote access to control everything if I wished. So why would pushing a some plain text code directly to their machine be so fundamentally different than all the other means of passing bits between our machines?
If you share screen you are in control of what you show, if you give someone SSH access, what would stop them from passing/running a small script to fetch everything you have or doing w/e with your computer? I mean it's a blatant security violation to me. Just no reason to do that.
In large corps you usually have policies to not leave your laptop unattended logged in, in the office, that would be potentially even worse than that.
It's not. Unless you work at a shitty place, something like what OP mentioned is far from a big deal and most people would wanna know more about it
The code is considered IP of the corp and they probably have rules around how or where IP should be shared, access controls etc.
I don't think it has anything to do with being old, this is what happens when your software gets too complex that nobody even knows the very basics. This is highlighted with the documentation, if the software's documentation becomes lengthy enough that it could be an entire book, you're going to be getting these sorts of articles from time to time. Another highlight is bash, that is a huge man page for what should be a shell.
Also relatively unknown: You can clone from a directory. It won't accomplish the backup feature but it's another option/feature.
If you do it over NFS or whatever then you can collaborate as well.
git over nfs ... not the very best idea.
I haven't tried it, but I think it's fine if only one person has write access to any given clone. You can pull back and forth between clones freely. It's if you have two Git clients trying to write to the same repo that you'll have problems.
Shared write access to the same git repo directory can be done sanely, but you have to get a number of things right (same group for all users, everything group writable, sticky bit on directories, set config core.sharedRepository=group): https://stackoverflow.com/a/29646155
Yes, when you're not on NFS. Maybe it works on NFS but I wouldn't bet my project on it. Fortunately at least with Git it's easy to have lots of backups.
Depends on what you mean by using etc.
If somebody asked me if it's possible to scp my git repo over to another box and use it there or vice versa, I would have said, yes, that is possible. Although I would've felt uneasy doing that.
If somebody asked me if git clone ssh:// ... would definitely work, I wouldn't have known out of the gate, although I would have thought it would be neat if it did and maybe it does. I may have thought that maybe there must be some sort of git server process running that would handle it, although it's plausible that it would be possible to just do a script that would handle it from the client side.
And finally, I would've never thought really to necessarily try it out like that, since I've always been using Github, Bitbucket, etc. I have thought of those as permanent, while any boxes I have could be temporary, so not a place where I'd want to store something as important to be under source control.
Am I misreading your comment?
You’ve always used GitHub but never known it could work over ssh? Isn’t it the default method of cloning when you’re signed in and working on your own repository…?
I have used SSH for GitHub of course, but the thought that I could also use it from any random machine to machine never occurred to me. And when it might occur to me, I would have thought that maybe SSH is used as a mechanism for authentication, but it might still require some further specialized server due to some unknown protocols of mine. I always thought of SSH or HTTPS as means of authentication and talking to the git server rather than the thing that processes cloning.
E.g. maybe the host would have to have something like apt install git-server installed there for it to work. Maybe it wouldn't be available by default.
I do know however that all info required for git in general is available in the directory itself.
most people think git = github
IT support and cybersecurity teams responsible for blocking and enforcing network access restriction to "github.com" ... blocked a user request to install "git" locally citing the former policy. The organization in question does IT services, software development, and maintenance as their main business.
Sometimes I feel like IT and security people compete on how to make the work least possible.
These guys won.
That’s… special.
Yup. I’ve heard several people say that Git is a product from Microsoft…
I wouldn't mind it if those people are from non-tech background.
Now, if it is a growing misconception among cs students or anyone doing software development or operations, that's a cause for concern.
The irony, when you realize that Linus Torvalds created git.
There's an interview with Torvalds where he states that his daughter told him that in the computer lab at her college Linus is more known for Git than Linux
Clip from the interview: https://www.youtube.com/shorts/0wLidyXzFk8
Looks like they’re not developers after all
Nonsense...
Even someone who knows that git isn't GitHub might not be aware that ssh is enough to use git remotely. That's actually the case for me! I'm a HUGE fan of git, I mildly dislike GitHub, and I never knew that ssh was enough to push to a remote repo. Like, how does it even work, I don't need a server? I suspect this is due to my poor understanding of ssh, not my poor understand of git.
Git is distributed, meaning every copy is isolated and does not depends on other's copy. Adding remotes to an instance is mostly giving a name to an URL(URI?) for the fetch, pull, push operation, which exchange commits. As Commits are immutable and forms a chain, it's easy to know when two nodes diverge and conflict resolution can take place.
From the git-fetch(1) manual page:
> Git supports ssh, git, http, and https protocols (in addition, ftp and ftps can be used for fetching, but this is inefficient and deprecated; do not use them).
You only need access to the other node repo information. There's no server. You can also use a simple path and store the other repo on drive.
Sort of related, but given that FTP is supported, I wonder how much work it would take to use telnet as a transport.
Doable. It would basically be ssh but without encryption. You'd have to bang out login by hand, but "username\npassword\n" will probably work, might need a sleep inbetween, and of course you'll have to detect successful login too. Oh, and every 0xff byte will have to be escaped with another 0xff
At that point, may as well support raw serial too.
Supporting rlogin on the other hand is probably as simple as GIT_SSH=rlogin
> There's no server.
There IS a server, it's the ssh daemon. That's the bit I had never thought about until now.
The server is git itself, it contains two commands called git-receive-pack and git-upload-pack that it starts through ssh and communicate through stdin/out
You can think of the ssh://server/folder as a normal /folder. ssh provides auth and encryption to a remote hosted folder but you can forget about it for the purpose of understanding the nature of git model.
SSH is just a transport to get access to the repo information. The particular implementation does not matter (I think). Its configuration is orthogonal to git.
It's just a transport, and it needs a server.
> I don't need a server?
You do, an SSH server needs to be running on the remote if you want to ssh into it, using your ssh client - the `ssh` command on your laptop. It's just not a http server is all.
You start that server using the `sshd` [systemd] service. On VPSs it's enabled by default.
Git supports both http and ssh as the "transport method". So, you can use either. Browsers OTOH only support http.
Exactly! Only now the dots connected. Thank you!!
Edit: hey this is really exciting. For a long time one of the reasons I've loved git (not GitHub) is the elegance of being a piece of software which is decentralized and actually works well. But I'd never actually used the decentralized aspect of it, I've always had a local repo and then defaulted to use GitHub, bitbucket or whatever instead, because I always thought I'd need to install some "git daemon" in order to achieve this and I couldn't be bothered. But now, this is so much more powerful. Linus Torvalds best programmer alive, change my mind.
And in general, any daemon that manipulates files can be replaced by ssh (or ftp) access and a local program.
And most things are files.
BTW, a nice example of this general concept is Emacs' TRAMP mode. This is a mode where you can open and manipulate files (and other things) on remote systems simply by typing a remote path in Emacs. Emacs will then simply run ssh/scp to expose or modify the contents of those files, and of course to run any required commands, such as deleting a file.
Did you know that you can use git locally? It works just like that because ssh is a remote shell.
Read https://git-scm.com/docs/git-init#Documentation/git-init.txt...
Anyway it sounds like you have a lot of holes in your git-knowledge and should read some man pages
No, you're wrong. These are holes in my ssh knowledge, and your comment makes me think you have the same holes.
lol you sound like a treat, dude
https://git-scm.com/book/ms/v2/Git-on-the-Server-The-Protoco...
I mean, you do need an ssh server. Basically ssh can run commands on the remote machine. Most commonly the command would be a shell, but it can also be git commands.
Yup! Someone else just pointed it out. Brilliant, thank you!
I always found these sort of categorical denigrations to be off base. If most people do think git = github then that's because they were taught it by somebody. A lot of somebodies for "most people". Likely by the same somebodies who also come to places like this. It has always taken a village to raise a child and that is just as true for an infant as a junior programmer. But instead we live in a sad world of "why didn't schools teach person x"
What makes you say that people complain about the spread of incorrect knowledge "instead" of teaching? Because there's nothing wrong with doing both.
Despite your indignation, the observation that most people think GitHub is git is entirely true. Do you point it out when you spot someone having that mistaken belief? I do.
they were taught by github
Humans are fallible, relying on hearsay is unprofessional, learn your craft properly.
Imagine what the equivalent argumentation for a lawyer or nurse would be. Those rules ought to apply for engineers, too.
I didn’t know either - or rather, I had never stopped to consider what a server needs to do to expose a git repo.
But more importantly, I’m not sure why I would want to deploy something by pushing changes to the server. In my mental model the repo contains the SOT, and whatever’s running on the server is ephemeral, so I don’t want to mix those two things.
I guess it’s more comfortable than scp-ing individual files for a hotfix, but how does this beat pushing to the SOT, sshing into the server and pulling changes from there?
There's a lot of configuration possible due to the fact that git is decentralized. I have a copy on my computer which is where I do work. Another on a vps for backup. Then one on the app server which only tracks the `prod` branch. The latter is actually bare, but there's a worktree for the app itself. The worktree is updated via a post-receive hook and I deploy change via a simple `git push server prod`
You actually led me into a dive to learn what worktrees are, how bare repos + worktrees behave differently from a regular clone and how a repo behaves when it’s at the receiving end of a push, so thanks for that!
I’ve never worked with decentralized repos, patches and the like. I think it’s a good moment to grab a book and relearn git beyond shallow usage - and I suspect its interface is a bit too leaky to grok it without understanding the way it works under the hood.
I actually realized this last week, and have yet to try it. Programming for almost fifty years, using Git for thirteen years, and not an idiot (although there are those who would dispute this, including at times my spouse).
Considering git is one of those things barely anyone knows how to actually use, yes
My theory is that git is just so easy to use without understanding it that you end up with lots of people using it without understanding it :)
It's not "so easy to use without understanding it", it's the opposite it has so much unnecessary complexity (on top of a brilliant simple idea btw), that once people learn how to do what they need, they stop trying to learn any more from the pile of weirdness that is git.
Decades from now, git will be looked back at in a similar but worse version of the way SQL often is -- a terrible interface over a wonderful idea.
I don't think that's true. In my experience it takes time, but once it clicks, it clicks. Sure, there is a bunch of weirdness in there as well, but that starts way further than where your typical git user stops.
I don't think git would end up this popular if it didn't allow to be used in a basic way by just memorizing a few commands without having to understand its repository model (however simple) well.
What are some fun/creative ways to do GitHub/GitLab style CI/CD with this method? Some kind of entry point script on push that determines what to do next? How could you decide some kind of variables like what the push was for?
Check the docs for the post-receive hook, it does give everything you need. I don't know what you have in mind by "GitHub/Gitlab style", but it's just a shell script, and you can add in as much yaml as you want to feel good about it.
I did a quick search for "post-receive hook ci" and found this one: https://gist.github.com/nonbeing/f3441c96d8577a734fa240039b7...
`man 5 githooks` is your friend. Hooks are just scripts and they can receive parameters. `post-receive` is most likely what you would want.
I wrote about that idea here: https://www.stchris.net/tiny-ci-system.html
I never thought about it. If somebody had asked me, yeah. Of course it makes sense. But it's just one of those things where I haven't thought about possibility.
Filesystems and folders are foreign and elusive concepts to gen Z.
https://www.theverge.com/22684730/students-file-folder-direc...
It gets better than that...
https://www.youtube.com/shorts/D1dv39-ekBM
A tip, you can put the hash in a regular youtube URL to get the full interface instead of the limited shorts one: https://www.youtube.com/watch?v=D1dv39-ekBM
I have encountered it in real life many times. These days I try to give jr's extra space to expose their gaps in things I previously assumed were baseline fundamentals - directories and files, tgz/zip files, etc
I imagine larger part of the developer community does not, in fact, know that GitHub is not git and one can get everything they need without feeding their code to Microsoft's AI empire. Just another "Embrace, extend, and extinguish"
Or just put the repo in a shared directory in a high-trust group of developers (or just yourself).
I was aware that it should be possible to interact directly with another repository on another machine (or, heck, in another directory on the same machine), which implies that ssh access is sufficient, but I was unaware of how that would be done.
There's definitely generational loss about the capabilities of git. In the beginning, git was a new version control option for people to explore, now git is the thing you learn to collaborate on github/lab/ea. I remember the Chagon book coming out as the peak between dense technical explainers and paint by numbers how-tos.
I would be surprised if more than 10% of git users know that. Would be equally surprised if more than 20% of git users know how to use ssh.
I think your age isn't the issue, but I suspect you're in a bubble.
The non-Windows bubble?
You probably want to use a bare repository (git init --bare) rather than `git config receive.denyCurrentBranch updateInstead`, which will cause your pushes to fail if you edit anything locally in the checkout. For http://canonical.org/~kragen/sw/dev3/ I run a pull from the post-update hook of http://canonical.org/~kragen/sw/dev3.git, http://canonical.org/~kragen/sw/dev3.git/hooks/post-update, which is short enough that I'll just include it here:
You can of course also run a local site generator here as well, although for dev3 I took a lighter-weight approach — I just checked in the HEADER.html file that Apache FancyIndexing defaults to including above the file directory listing and tweaked some content-types in the .htaccess file.This could still fail to update the checkout if it has local changes, but only if they create a merge conflict, and it won't fail to update the bare repo, which is probably what your other checkouts are cloned from and therefore where they'll be pulling from.
Also bare repositories are a useful thing to put on USB pendrives.
regarding that post-update script, can you explain?
I would think you'd want to
..in that order.And I wouldn't think you'd need to run git update-server-info again, after git pull. My understanding isthe update-server-info makes updates to info/refs , which is necessary _after a push_.
What am I missing?
The first update-server-info is running in the bare repo, which is the place I just pushed to, which is where sw/dev3 is going to pull from.
I'm not sure the second update-server-info is necessary.
Cannot emphasize this whole notion enough; Very roughly, Github is to git what gmail is to email.
It's mostly probably fine if that's the thing most of everybody wants to use and it works well; but also it's very unwise to forget that the point was NEVER to have a deeply centralized thing -- and that idea is BUILT into the very structure of all of it.
This reminded me of another discussion on HN a few months ago. Wherein I was reflecting on how the entire culture of internet standards has changed over time:
"In the 80s and 90s (and before), it was mainly academics working in the public interest, and hobbyist hackers. Think Tim Berners-Lee, Vint Cerf, IETF for web/internet standards, or Dave Winer with RSS. In the 00s onward, it was well-funded corporations and the engineers who worked for them. Think Google. So from the IETF, you have the email protocol standards, with the assumption everyone will run their own servers. But from Google, you get Gmail.
[The web] created a whole new mechanism for user comfort with proprietary fully-hosted software, e.g. Google Docs. This also sidelined many of the efforts to keep user-facing software open source. Such that even among the users who would be most receptive to a push for open protocols and open source software, you have strange compromises like GitHub: a platform that is built atop an open source piece of desktop software (git) and an open source storage format meant to be decentralized (git repo), but which is nonetheless 100% proprietary and centralized (e.g. GitHub.com repo hosting and GitHub Issues)." From: https://news.ycombinator.com/item?id=42760298
Yes. And honestly though, this is the sort of thing that makes me generally proclaim that Free Software and Open Source won.
It was extremely unlikely that it would be some kind of free utopia; but also, it's extremely remarkable what we've been able to keep generally free, or at least with a free-enough option.
Idk if git was designed to not be used in a centralized way. Like all other common CLIs, it was simply designed to work on your PC or server without caring who you are, and nothing stopped a corp from turning it into a product. Torvalds made git and Linux, then he put Linux on Github.
It's not a "CLI" and yes, "decentralized" was literally one of the points of it.
Git was explicitly designed to be decentralized.
DNS is in the same predicament. :-p
Just make the repository on the server side bare and you won't have to worry about checked out branches or renaming ".git" directory.
> This is a great way to [...] work on server-side files without laggy typing or manual copying
This is the usecase mentioned in the article and it wouldn't work with a bare repo. But if the server your SSH'ing to is just a central point to sync code across machines, then you're right: multiple hoops mentioned in the article are solved by having the central repo bare.
yeah it seems odd that they don't just have remote> $HOME/repos/foo.git and then clone from there locally and remotely
FWIW a single user working on a remote versioned directory is indeed a reasonable use-case for receive.denyCurrentBranch=updateInstead, but IMO the article should have made it clear that it's not necessarily a good choice in general.
My favorite git trick is using etckeeper & git subtree to manage multiple machines from a single repo . A single git repo can “fan out” to dozens of instances . It’s useful even for “managed” hosts with terraform because etckeeper snapshots config with every change, catching bugs in the terraform config.
During the dev / compile / test flow, git makes a lightweight CI that reduces the exposure to your primary repo . Just run `watch -n 60 make` on the target and push using `git push` . The target can run builds without having any access to your primary (GitHub) repo.
The more I use git, the more I discover more depth to it.
So many features and concepts; it's easy to think you understand the basics, but you need to dig deep into it's origin and rationale to begin to grasp the way of thinking it is built around.
And the API surface area is much larger than one would think, like an iceberg
So I find it really weirdly low level in a way. Probably what is needed is is a higher-level CLI to use it in the most sensible, default way, because certainly the mental model most people use it with is inadequate.
I have been doing this for many years.
If you want a public facing "read only" ui to public repositories you can use cgit (https://git.zx2c4.com/cgit/about/) to expose them. That will enable others to git clone without using ssh.
I keep my private repositories private and expose a few public ones using cgit.
Huh, I never realized that cgit was created by the same person that created wireguard.
I remember the first time I tried git, circa 2006, and the first 3 commands I tried were:
And it didn’t work. You have to ssh to the remote server and “git init” on a path first. How uncivilized.Bitkeeper and a few other contemporaries would let you just push to a remote path that doesn’t exist yet and it’d create it. Maybe git added this since then, but at the time it seemed like a huge omission to me.
Hah, you made me check whether clone's second argument can be a URL. But no, it's explicitly "<directory>", so it can't be used as a equivalent of "git push --mirror" :)
I suspect many who always use git remotely don't know that you can easily work with local repositories as well using the file protocol, git clone file:///path/to/repository will create a clone of the repository at the path.
I used that all the time when I had to move private repositories back and forth from work, without ssh access.
> It’s also backed up by default: If the server breaks, I’ve still got the copy on my laptop, and if my laptop breaks, I can download everything from the server.
This is true, but I do also like having backups that are entirely decoupled from my own infrastructure. GitHub personal private accounts are free and I believe they store your data redundantly in more than one region.
I imagine there's a way to setup a hook on your own server such that any pushes are then pushed to a GitHub copy without you having to do anything else yourself.
Git post-update hooks to do deployment FTW. I looked into the whole push-to-github to kick off CI and deployment; but someone mentioned the idea of pushing over ssh to a repo on your server and having a post-update hook do the deployment, and that turned out to be much simpler.
As a git user "not by choice" (my preference going for mercurial every single day), I never understood why git needs this distinction between bare/non-bare (or commit vs staging for that matter). Seems like yet another leaky abstraction/bad design choice.
Jujutsu make the interaction sane, and is far more logical than even mercurial (that I love too!)
A repo is as database containing a tree of commits. Then you got the concept of branch, which points to a specific commit. Then there's the special pointer HEAD which is the latest commit for the current worktree.
When you checkout (now switch) a branch, HEAD is now the same as the branch (they point to the same commit). When you do operation like commit, reset, reset,... both the head and the branch are updated. So if a remote node tries to update the local node via a push on its end, that would mess up the local worktree. So you create a bare repo instead which can't contain a local worktree.
Note: A worktree is computed from the initial commit to the commit currently identified by HEAD by following the parent information on each commit.
The staging area is like a stored snapshot of what you would like to commit. You can always create patch between HEAD and the worktree, edit it, and then save the patch as the commit, then apply the leftover to the worktree. The staging just make that easier. It's a WIP patch for the next commit.
Mercurial has no distinction between a bare repo and a non-bare repo: any repo can have a working copy or not. You can check out a working copy with `hg update somerevision`, or get rid of it with `hg update null`.
You can push to a repo with a working copy, if you like; nothing will happen to that working copy unless you run `hg update`. Since you don’t need a working copy on the server’s repo, you never run `hg update` on it, and it’s effectively what git calls a bare repository.
> When you checkout (now switch) a branch, HEAD is now the same as the branch (they point to the same commit).
Actually, HEAD now points to that branch, which in turn points to the commit. It's a different state than when HEAD points directly to the same commit (called "detached HEAD" in Git's terminology) where this issue doesn't happen as you're not on a branch at all. It's a subtle, but important distinction when trying to understand what happens under the hood there.
You're right. I was trying to simplify.
So, exactly as DrinkyBird said: I still don't see a good reason for this distinction to exist, what's in the repo's history and in its working directory are orthogonal concepts that are tied together by a bad UX for no apparent gain.
Yeah, I am in the same boat. My files are either non-staged or committed about 99.99% of the time. For me the concept of staging is completely useless
Staging is immensely useful in more than one case.
Case one: WiP on a branch, code is pretty stable, but I want to do some experiments which will likely be deleted. I stage everything and then make (unstaged) changes which I can then undo with two keystrokes.
Case two: I'm reviewing a complex PR, so I first merge it with --no-commit, then unstage everything and then stage chunks (or even individual lines) I have already reviewed.
Case three: I was coding in the state of flow and now I have a lot of changes I want to commit, but I want to separate them into several atomic commits. I stage the first batch of changes, commit, then stage another, commit, etc.
There are probably more, but these three alone are worth having the staging area.
Case one: you don't need staging. You can stash, or just commit and checkout HEAD^
Case two: you don't need staging. You can stash, and then unstash incrementally (I would be shocked if git doesn't have the equivalent of `hg unshelve --interactive` and its keyboard friendly TUI)
Case three: you don't need staging. You can just edit/amend the series (rebase --interactive I believe you guys call that).
That is to say, all that you want to put in your stash, you could commit directly to the DAG, and edit to your convenience, with the regular history-rewriting tools already at your disposal. And the off-DAG stuff can be handled by stash (and even there, a normal commit that you would rebase to its destination would perfectly do).
And what I described is incidentally what https://github.com/jj-vcs/jj does, which can be pretty-well described as "taking the best of all major VCSes"
Though I wasn't trying to say that there is no need for staging-based workflows, I was just saying that there is nothing in terms of convenience or capabilities that the staging area does that can't be achieved with just regular commits and amending/rewriting.
The immediate response from many git users when confronted to alternative VCSes is "well, it doesn't have a staging area, so it's obviously inferior" instead of going with "let's see how differently they approach this problem, and perhaps I will like it/git isn't all perfect after all".
Beware of using this to publish static sites: you can accidentally expose your .git directory to the public internet.
I got pwned this way before (by a pentester fortunately). I had to configure Apache to block the .git directory.
Instead of excluding non-public directories, I like to make an explicit `public` directory (or `doc`, `doc-root`, whatever you want to call it). Then configure your server to point to that subdirectory and don’t worry about the repo.
I usually throw `etc` and `log` directories at the top level as well and out my server config in etc, and have a gitignite rule to ignore everything in logs, but it’s there and ready for painless deployment.
Since the web root is already a sub directory, more sensitive things can go into the same repo without worrying about exposing them.
But what, exactly, was pwned? Did you have secrets in the git repo?
No secrets like auth credentials or tokens but:
- Deleted files and development artifacts that were never meant to go public.
- My name and email address.
- Cringy commit messages.
I assumed these commits and their metadata would be private.
It was embarrassing. I was in high school, I was a noob.
I expose the .git directories on my web server and never considered it a problem. I also expose them on GitHub and didn't consider that a problem either...
Super common failure is accidental commit of a secret key. People suck at actually deleting something from git history. Had one colleague leak a Digital Ocean key this way with an accidental env file commit. He reverted, but the key is of course still present in the project history.
The speed at which an accidentally committed and reverted key is compromised and used to say launch a fleet of stolen VPSes on a github public repo nowadays is incredible. Fortunately most of the time your provider will cancel the charges...
This has always been the roughest part of git for me, the process to remove accidentally committed sensitive content. Sure we should all strive not to commit stupid things in the first place, and of course we have tools like gitignore, but we are all only human.
> https://docs.github.com/en/authentication/keeping-your-accou...
"Sensitive data can be removed from the history of a repository if you can carefully coordinate with everyone who has cloned it and you are willing to manage the side effects."
This is how Heroku has been doing it for years since it started out 10+ years ago.
$ git push heroku master
So you'll have to make sure to push to e.g. GitHub as well for version control.
Back when I started at my current job... 15 years ago... We had no central git server. No PR workflow. We just git pull-ed from each others machines. It worked better than you would expect.
We then went to using a central bare repo on a shared server, to hosted gitlab(? I think - it was Ruby and broke constantly) eventually landing on GitHub
This is classic git usage. A "pull request" was literally just asking someone to pull from your branch. GitHub co-opted the term for their own thing.
The thing that people really don't seem to get these days is how your master branch is a different branch from someone else's master branch. So pulling from one master to another was a normal thing. When you clone you get a copy of all the branches. You can commit to your master branch all you want, it's yours to use however you want to.
There was a brief period when Google Cloud had support for hosting git on a pay-per-use basis. (I think it was called Google Cloud Repositories.) It had a clunky but usable UI.
I really preferred the idea of just paying for what I used -- rather than being on a "freemium" model with GitHub.
But -- as many things with Google -- it was shutdown. Probably because most other people do prefer the freemium model.
I wonder if this kind of thing will come back in style someday, or if we are stuck with freemium/pro "tiers" for everything.
How would I sync access, if more than one people ssh-pushes onto the git repo? I assume syncing be necessary.
Same as always, with any other remote?
(Use `git pull`? If the different people push to different branches, then there's no conflict and no problem. If you try to push different things into the same branch, the second person will get told their branch is out of date. They can either rebase or - if this is allowed by the repo config - force push over the previous changes...)
Sure, if they push one after the other. If they push at the same time however, does Git handle the sync on its own?
I've used Git over SSH for several years for personal projects. It just works with no additional overhead or maintenance.
Tip: create a `git` user on the server and set its shell to `git-shell`. E.g.:
You might also want to restrict its directory and command access in the sshd config for extra security.Then, when you need to create a new repository you run:
And use it like so: Or: This has the exact same UX as any code forge.I think that initializing a bare repository avoids the workarounds for pushing to a currently checked out branch.
Yes, that's how I use it too.
However, this setup doesn't work with git-lfs (large file support). Or, at least I haven't been able to get it working.
PS: Even though git-shell is very restricted you can still put shell commands in ~/git-shell-commands
To my knowledge git-lfs is only really designed to store your large files on a central server. I think it also uses its own out-of-band (from the perspective of git) protocol and connection to talk to that server. So it doesn't work with a standard ssh remote, and breaks git's distributed nature.
For an actually distributed large file tracking system on top of git you could take a look at git-annex. It works with standard ssh remotes as long as git-annex is installed on the remote too (it provides its own git-annex-shell instead of git-shell), and has a bunch of additional awesome features.
Yes exactly, creating git user on Linux machine and configuring it just for git turned out to be easiest way how to get Source Tree and Git in Windows work with it out of the box.
This is definitely nice but it doesn’t really support the full range of features of Git, because for example submodules cannot be local references. It’s really just easier to set up gitolite and use that in almost the same exact way but it’s much better.
What is it with code on blog posts where fonts have uneven size and/or font types (e.g. italics mixed in with regular)? I see this from time to time and I wonder if it’s intentional.
Found a solution to this recently (this is not my blog): https://nathan.rs/posts/fixing-ios-codeblocks/
CSS needs some tweaking for iOS Safari, I guess.
Seen this a lot as well with Safari on the iPhone.
Docs:
https://git-scm.com/docs/git-clone#_git_urls
https://git-scm.com/docs/git-init
One note, xcode and maybe some other clients can't use http "dumb mode". Smart mode is not hard to set up, but it's a few lines of server config more than this hook.
TIL about the update options for checked out branch. In practise though usually you want just the .git "bare" folder on server
I feel like this is a bug that Xcode should fix
There are many bugs Xcode should fix.
I am surprised how little software engineers (even those that use) know about git.
That's because git is hard to use and full of commands which are making no sense. Eventually people will learn to just clone, pull, push and occasionally merge and be done with it.
People said the same thing about “advanced” operations with cvs and svn (and just called their admin for p4 or source safe). But I really don’t understand the sentiment.
Managing code is one of the cornerstones of software engineering. It would be like refusing to learn how to use a screwdriver because someone really just wants to hammer things together.
The great thing about $your-favorite-scm is that it transcends language or framework choices and is fungible for early any project, even outside of software. I’m surprised it isn’t part of more professional tools.
> Managing code is one of the cornerstones of software engineering. It would be like refusing to learn how to use a screwdriver because someone really just wants to hammer things together.
Ok, then make the commands make sense. For example 90%+ people has no idea what rebase does, yet it is a useful command.
People does not want to learn with git outside of what works, because they can't experiment. The moment they will "hold it wrong" whole repo will break into pieces, unable to go forward or backwards. Hopefully they did not commit.
Git feels like a hammer covered in razor blades. The moment you will try to hold it differently you will cut yourself and somebody else will need to stich you up.
You can definitely experiment. Make a copy of the directory and experiment on that copy without pushing. I have done it a million times.
Most people would just use `app` `app (final)`, `app (final 2)`, etc... VCS exists for a reason and I strongly believe that the intersection of people that say git is hard and people that do not know why you want a VCS is nearly a perfect circle.
Being a useful tool does not justify having an extremely inconsistent and unnecessarily confusing UI.
Interesting. I am just trying to decide between self-hosting Forgejo and other options for hosting Git in own private network.
One of my favorite tools available for Linux is called gitolite. It's in the Debian repo.
https://gitolite.com/gitolite/
If you think the bare bones example is interesting and want something simple just for you or a small group of people, this is one step up. There's no web interface. The admin is a git repository that stores ssh public keys and a config file that defines repo names with an ACL. When you push, it updates the authorization and inits new repositories that you name.
I put everything in repos at home and a have multiple systems (because of VMs) so this cleaned things up for me considerably.
I really like forgejo, but the git hosting bit is really just one feature for me. Their ci/cd runners, package repos and such are all things I need and forgejo includes in one nice bundle.
If I was just using it for git hosting I'd probably go for something more light weight to be honest.
Could also consider running a Tangled knot (lightweight, headless git servers): https://tangled.org
Does this support private repositories with collaboration?
Not yet, unfortunately. Mostly due to protocol limitations—we use AT (https://atproto.com) for federation.
That looks definitely interesting!
A lot of people do host Forejo but unless you are actually working with other people and they need a reduction in access via pull requests it doesn't do much other than provide a pretty GUI to look at. The bare SSH approach makes more sense for personal projects.
am using gitea. but thinking of switching to serve (charm).
I'm also using gitea, running on RPI5. Setup took like 15 mins, highly recommend.
mine is running on an rpi zero w (v1). super low power consumption.
Forgejo is working okay for me.
Hard to justify using SSH for Git. Principle of least power and all that
Git is distributed, so there's no least power and all that. Everyone has full power over their own copy. What you want is one copy being the source of truth. You can always use HTTP for read-only access to that copy with a limited set of people having write access to update the copy. Patches can be shared via anything (git has built-in support for email).
The proper way to do this to make a "bare" clone on the server (a clone without a checked out branch). I was doing this in 2010 before I even signed up to GitHub.
There’s also git daemon.
“By default, git won’t let you push to the branch that is currently checked out”
TIL that people use non-bare git.
I do something similar. I create a bare repo on my dropbox folder or nas mount. Then checkout from bare repo file path to some place where I will be doing all the work.
My git "server" is a folder of bare git repositories in home directory which I share with Syncthing.
It'd be great if there was more specific support. But in practice? No problems so far.
Perhaps the only issue with this setup is that you lose some of the robustness of git: mess up one repo beoynd repair, and you've just messed up all the checkouts everywhere.
I sync my repos manually (using GitHub as the always-on remote, but I'm not particularly attached to it). This gives me more resilience should I blow up the repo completely (hard to do, I know).
They're not checked out repos. They're bare repos, which I then checkout from.
The benefit is that git repos are essentially append only in this mode.
The folder itself is scheduled into an encrypted backblaze backup too.
this article is very bad advice. this way things are extremely brittle and there's a reason all those settings are disabled by default. you will lose data, save from very specific use cases
the vastly superior way is 'git bare' which is a first class supported command without hacky settings.
I tried this and it is never as smooth as described.
Why is GitHub popular? its not because people are "dumb" as others think.
Its because GitHub "Just Works".
You don't need obscure tribal knowledge like seba_dos1 suggests [0] or this comment https://news.ycombinator.com/item?id=45711294
The official Git documentation for example has its own documentation that I failed to get work. (it is vastly different from what OP is suggesting)
The problem with software development is that not knowing such "tribal knowledge" is considered incompetence.
People don't need to deal with obscure error messages which is why they choose GitHub & why Github won.
Like the adge goes, "Technology is best when it is invisible"
[0] https://news.ycombinator.com/item?id=45711236
[1] https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-...
> I tried this and it is never as smooth as described.
I think your comment shows some confusion that it's either the result or cause of some negative experiences.
Starting with GitHub. The primary reason it "just works" is because GitHub, like any SaaS offering, is taking care of basic things like managing servers, authorization, access control, etc.
Obviously, if you have to setup your own ssh server, things won't be as streamlined as clicking a button.
But that's obviously not the point of this post.
The point is that the work you need to do to setup a Git server is way less than you might expect because you already have most of the things already set, and the ones that aren't are actually low-hanging fruit.
This should not come as a surprise. Git was designed as a distributed version control system. Being able to easily setup a stand-alone repository was a design goal. This blog post covers providing access through ssh, but you can also create repositories in any mount point of your file system, including in USB pens.
And, yes, "it just works".
> The official Git documentation for example has its own documentation that I failed to get work. (it is vastly different from what OP is suggesting)
I'm sorry, the inability to go through the how-to guide that you cited has nothing to do with Git. The guide only does three things: create a user account, setup ssh access to that account, and create a Git repository. If you fail to create a user account and setup ssh, your problems are not related to Git. If you created a user account and successfully setup ssh access, all that is missing is checking out the repo/adding a remote repo. If you struggle with this step, your issues are not related to Git.
Are basic git concepts like bare repos "obscure tribal knowledge" these days? What do you think ".git" directory is?
Having to make a repo bare to not have issues with branches is definitely obscure.
It's obvious as soon as you consider that your push will overwrite a ref that's currently checked out in the target's repo workdir. The exact same thing happens when pushing to local repos. You don't have to make a repo bare to avoid this issue, but it's certainly the easiest way to avoid it altogether when you don't need a workdir on the server side.
It's obvious that it needs to update the ref. It's not obvious that this would cause any problems. You could fix HEAD as part of writing the ref. Automatically managing HEAD is normal git behavior.
It's obvious that something non-obvious would have to happen with the workdir behind the user's back. Imagine that you are working with your workdir while someone else pushes something to your repo. Bailing out is the only sane option (unless something else has been explicitly requested by the user).
Nothing has to happen to the workdir if you fix HEAD.
...except of all the things that rely on the HEAD pointing to another ref now changing their behavior. gbp will by default bail off if HEAD is not on a branch, "git commit" won't update the ref you thought it will cause you're now suddenly on "detached HEAD" etc.
I've never heard of... debian package builder? I don't care if it gets annoyed; if that's one of the biggest issues then that's a good sign for the method.
Yes the commit won't be on the branch you want, but you'd get about the same issue if the two repos had a bare upstream. The branch diverges and you need to merge. It's a bit less ergonomic here but could be improved. Git could use branch following improvements in general.
> Yes the commit won't be on the branch you want, but you'd get about the same issue if the two repos had a bare upstream.
Not at all. The commit would have "landed" on the exact branch you thought it will. How it will be reconciled with a diverged remote branch is completely orthogonal and may not even be of concern in some use cases at all.
The situation is almost identical except you don't have a cute name for your new commit. Let's say you add a ref to your detached commit, perhaps local/foo. Then you're looking at a divergence between foo and local/foo. If you had a bare upstream it would be a divergence between origin/foo and foo. No real difference. And if you don't want to reconcile then you don't have to.
If git was a tiny bit smarter it could remember you were working on "foo" even after the ref changes.
Of course it could, but that doesn't yet mean it should. A checked-out ref is considered to be in-use and not to be manipulated (unless done in tandem with HEAD), not just by "git push" but also other tools like "git branch". It's consistent and, IMO, less surprising than what you propose. It could be an optional behavior configured by receive.denyCurrentBranch, though I don't see a good use-case for it that isn't already handled by updateInstead.
If someone pushes to a repo you should expect the refs to change. In some sense doing nothing avoids surprise but it's a bad way to avoid surprise.
But my real point is that refusing to act is not "the only sane [default] option" here. Mild ergonomic issues aren't a disqualifier.
If you use "git branch -d" you should expect the ref to be deleted, and yet:
> error: cannot delete branch 'main' used by worktree at '/tmp/git'
You could build the system differently and what seems like a sane default would be different there, but it would be a different system. In this system, HEAD isn't being manipulated by things not meant to manipulate it.
It wasn't obscure before GitHub.
Still, I like the online browser, and pr workflow.
Yeah this is the best arguments for GitHub type of web git GUI. Not knowing bare repo seems just like a devs not reading docs. And I'm sorry in this day and age devs needs to keep up and just type git like curl http://...../install.sh type of thing.
However would NEVER trust Github since the MS acquisition. codeberg and https://forgejo.org are perfectly sound FOSS alternative to GitHub and GigLabs nowdays.
The vast majority of developers working with git daily don’t know what a bare repo is, or that it exists at all. It’s not obscure knowledge as such, it’s just never come up for them as something they need.
The vast majority [0] of developers working with git daily have no mental model of git repos and just do a mental equivalent of copy'n'pasting commands and it's enough to let them do their work (until something breaks at least), so it doesn't seem like a particularly good indicator of whether something is obscure or not. There are many obscure things hiding in git, bare repos aren't one of those :)
[0] Source: pulled out of my arse.
Now try to add a submodule X (which is a bare repository) to your repository Y
Good job, now you can't add it nor remove it, without manually removing it in .git folder.
The cool thing is that once you know how simple it is to self host (I certainly didn't know before, just used github), you learn a skill that you can apply to many different contexts, and understand better what actually goes on in systems you depend on. That's what these "tech should be invisible" people miss, where they tout that you should instead learn SASS solutions where you have zero ownership nor agency, instead of taking the time to learn transferable skills.
> obscure tribal knowledge
The knowledge is neither obscure nor tribal, it is public and accessible. And likely already on your system, in the form of man-pages shipped with your git binaries.
> The problem with software development is that not knowing such "tribal knowledge" is considered incompetence.
Consequently.
It is "incompetence," or at the very least, it is unwise.
At the very least, a huge part of the intent of Git's very design was decentralization; though as is the case with many good tools, people don't use them as they are designed.
Going further, simply because "deeply centralized Git" is very popular, does not AT ALL determine that "this is the better way to do things." Please don't frame it as if "popular equals ideal."
God forbid we learn how our tools work.
> Its because GitHub "Just Works".
IPv6 still doesn't work with GitHub: https://doesgithubhaveipv6yet.com/
> Its because GitHub "Just Works".
Unfortunately (though expected), ever since Microsoft took over this has devolved into GitHub "sometimes works".
People use github because it has a bunch of features outside git and because they don't already have a server.
Not because it's hard or obscure to put git on your server.
I understand where you're coming from, but this seems like a terrible defeatist attitude to have.
What are we supposed to do ... throw our hands up because GitHub won?
I'll be down voted, but I'll say it. If you hold that attitude and you don't learn the fundamentals, if you don't understand your tools, you're a bad developer and a poor craftsman. You're not someone I would hire or work with.
git is not "the fundamentals". It's a tool that's very difficult to learn but we are forced to use because "it won" at some point.
Git's difficulty is NOT intrinsic; it could be a much better tool if Torvalds were better at UX. In short, I don't blame people who don't want to "learn git". They shouldn't have to learn it anymore than one learns to use a browser or Google docs.
Git isn't fundamental, but version control is. If you're doing development without it, you're making a mistake.
You're likely using a VCS, which is likely git (or jj, hg, fossil, tfs, etc).
Therefore, you should know how to use whatever you're using. It shouldn't be "invisible" to you.
> Technology is best when it is invisible
For normal users. Having this tribal knowledge is basically what makes developer and it’s their job to make technology invisible for others. Someone has to be behind the curtain.
> Why is GitHub popular? its not because people are "dumb" as others think.
> Its because GitHub "Just Works".
Git also "just works". GitHub simply offers a higher level of abstraction, a graphical UI, and some value-add features on top of Git. How much better all this really is arguable. I would say that it's disastrous that most developers rely on a centralized service to use a distributed version control system. Nevermind the fact that the service is the single largest repository of open source software, owned and controlled by a giant corporation which has historically been hostile to OSS.
GitHub "won" because it came around at the right time, had "Git" in its name—which has been a perpetual cause of confusion w.r.t. its relation with Git—, and boosted by the success of Git itself largely due to the cult of personality around Linus Torvalds. Not because Git was technically superior, or because GitHub "just works".
> You don't need obscure tribal knowledge
As others have said, a bare repository is certainly not "tribal knowledge". Not anymore than knowing how to use basic Git features.
> Like the adge goes, "Technology is best when it is invisible"
Eh, all technology is an abstraction layer built on top of other technology. Whether it's "invisible" or not depends on the user, and their comfort level. I would argue that all abstractions also make users "dumber" when it comes to using the layers they abstract. Which is why people who only rely on GitHub lose the ability, or never learn, to use Git properly.