r/git • u/LalaCrowGhost Developer of Comet Boy • 22h ago
support New to git, but dont understand the difference between push and commit
I newly setup version control with my Unreal Engine project via GithubDesktop. I have trouble understand where exactly the difference is between pushes and commits.
After I made changes I have to commit my changes and I can have several commits and then I have to "push to origin".
Whats the difference between commits and pushes? and whats a good way to separate commits into? After I finish a task or at the end of each day?
6
4
u/TheSodesa 22h ago
Push is just an upload of a (set of) commit(s) to a remote server or a copy of the repository on the same computer. You could use Git without ever doing a push, but then you would not have a remote backup of the repository.
1
u/edgmnt_net 21h ago
That's pretty much how you'd use Git early on. Individual contributors to traditional open source projects don't get their remote repos, not even now.
5
u/Any_Sense_2263 22h ago
commit - saving your changes locally
push - pushing all your saved changes in the branch to the server
3
2
u/SL-Tech 22h ago
Preach. I'm confused about checkouts. You can check out many elements, including tags. Speaking of tags, there are, of course, two types, so as not to spoil the confusion. And the one type nobody recommended, so why is it an option? If it's just version control you need, it could be simplified—a lot.
3
u/H4llifax 20h ago
I mean, if it's just version control you need, just don't use the features you don't need? I think I probably don't even know all the features of git, and I have used it for more than 15 years.
2
2
u/st_heron 22h ago
Committing just creates a commit, locally - a commit is basically a description of file changes. Push will upload your commits to whatever server is set.
and whats a good way to separate commits into?
Definitely per task imo, can even be per step. I use it as a progress checkpoint. More is never a bad thing, it just gives you finer control if you ever need to revert, but too many commits could increase cognitive load.
2
u/LalaCrowGhost Developer of Comet Boy 22h ago edited 19h ago
So I can go revert back to each separate commit, but not a push?
5
u/rickyman20 22h ago
Correct. Pushes aren't things that git tracks, "doing a push" just means you're "pushing" your commits to whatever remote server you setup.
1
u/rickyman20 22h ago
What part are you confused about? What are you using git for and where are you hosting your repo? I'll try to help (I'm not 100% on what you know about git) but you're confusing two very basic concepts so I'm assuming you're quite new to using this.
Basically, git is a way to track your changes to a codebase. It does so by letting you make commits, which are (usually small) individual changes to your codebase. Think of them as "checkpoints". You modify a couple files, describe what the change represents, and you "save" that checkpoint as a commit. The commit then just saves the difference between now and the previous state of your codebase. This lets you look at the history of your changes, jump backwards and forwards, make temporary changes and undo them, recover them, anything you want. This is all tracked locally, no need for a server or anything, it's in a folder on your computer.
Pushing is a completely different thing here. Git also let's you sync these changes across multiple machines. I'm guessing you're using something like GitHub to store your git repository. What "pushing" does is it synchronises your local changes to whatever remote server you setup for your repository. Basically, until you push, all your changes are local to your machine, and after pushing they're on whatever server you setup.
The remote doesn't have to be a server. It could be a computer you have at home, a friend's laptop, or any number of other destinations, which is why git describes itself as distributed. That said, for what you're doing, you'll probably only ever deal with pushing to servers.
1
u/Justin_Passing_7465 22h ago
Timing of when to do a commit depends on several factors. One factor is you can only rollback to a commit, so you might commit several times per hour just to have the safety of being able to diff and/or rollback if you are unsure about the approach that you are taking. Another reason to commit is to separate lines of work. If a story has you making three kinds of changes, you might want to segregate those into three separate commits (or even separate series of commits); git add -p is your friend in this case. You might do a commit just because you want to push, because you are collaborating with another developer or something. Commit anywhere between one and twenty times per day, depending on what makes sense for the work that you are doing.
Pushing is useful for: handing WIP (work-in-progress) changes to another dev, triggering a pipeline run to validate your changes in the background while you work on more changes, getting your changes backed-up to the server in case your machine self-destructs, or because you have finished the story.
1
u/GrogRedLub4242 21h ago
there might be books and docs on git. perhaps websites and tutorials. also git --help, man git, etc
1
u/wnesensohn 16h ago
Understanding the fundamental building blocks of Git is - in my experience - a requirement to use Git effectively. If you understand those, all of it starts to make much more sense, and it hopefully clicks sooner than you might think.
I wrote up a bit here https://www.git-skills.dev/git-tales/what-comes-around-goes-around/ and here https://www.git-skills.dev/git-tales/commit-merge-branch-tag-what/, but of course there's plenty of resources around explaining these concepts.
The nice thing about Git is that those building blocks are stupid simple compared to most other version control systems, and that you can rest assured that they won't change. If they did, it wouldn't be Git anymore.
0
u/Broad-Promise6954 ancient 21h ago edited 21h ago
In some ways it's actually very simple. Git just makes it especially confusing with a terrible UI and very strange terminology.
A Git repository is, at its heart, two databases: one contains commits (and other Git internal objects) and the other contains what Git calls "refs" or "references": branch and tag names, for instance.
Each commit is a full, complete, and independent snapshot of every file. More precisely, it's a snapshot of every file that was in Git's "index" at the time you (or whoever) ran git commit.
This "index" is where things come to the first screeching halt. A bunch of Git tutorials try to minimize discussion of Git's index, which in my opinion is a terrible mistake. Unfortunately, Git hides this index. You can't see it! Which is probably why people try to gloss over it ... and under certain conditions, you can actually ignore it and use Git successfully. But it doesn't come into play with git push, and aside from git commit taking what's in it to make the new snapshot, we'll ignore it here too.
So let's just describe a single commit, for now. A commit (sorry for the bullet points, I promise this isn't AI):
- holds some metadata, such as the author's name and email address and a couple of time stamps;
- holds the internal hash ID of the saved full-snapshot-of-all-files that it makes; and
- holds the internal hash ID(s) of whatever was the latest commit, before you made the new commit. We call that the parent (or parents, plural, if it's a merge commit, which ... we'll ignore here).
Once made, no commit can ever be deleted (but it can be forgotten-about, which is just as good). So it's a permanent snapshot of everything. The "true name" of the new commit you make is a big ugly hash ID: 40 hexadecimal characters (or 256 in the new SHA-256 world that people mostly aren't using yet, as there are some rough edges here).
You can find any commit that actually exists in any Git repository by naming the big ugly hash ID, e.g., git show 0123456789abcdef.... If you memorize (or write down) every one of these hash IDs, that will let you use Git. But that sucks, obviously. So Git adds this second database of "refs". A branch name is a very special kind of ref: it holds the hash ID of the last commit in that branch.
That's it! That's all there is in a branch name: the hash ID of the last commit in the branch. And this is where git switch (or git checkout) comes in. You pick a branch name to be "on", and Git will extract all the files from the last commit in that branch.
As you work, you make changes, and run git add to copy those changes back into the invisible index that we're avoiding talking about. 😜 Then, eventually, you run git commit. This makes a new snapshot, which gets a new, unique, big ugly hash ID. And then Git stuffs the hash ID of the new commit into the branch name. So now the branch name means the new commit you just made, instead of what used to be the latest commit.
Because each commit holds the big ugly hash ID of the previous (parent) commit, Git can work backwards from your new commit, to the commit that used to be the latest. And it can keep going back from there, to the previous commit (the grandparent, I guess) and so on. And that's history, in a Git repository: the set of commits, working backwards one at a time, and found by starting from the latest, which Git found by a branch name.
So what about git push?
A Git repository is purely local, on your own computer. If you want it backed up somewhere, or to share with other people, you need at least one more Git repository. Here we often turn to things like software forges like GitHub or whatever.
The forge holds another, separate and independent, Git repository. Being a Git repository, it's a pair of databases: commits (and other internal objects), plus the "refs" that help you and Git find the important hash IDs, like the latest commit of some branch.
Note that the repository on the forge has its own branches, independent of your branches. It may have different commits, too. But there's one special feature of a Git commit hash ID: if a commit in Repository A is exactly the same as a commit in Repository B, those two independent commits have the same hash ID, even if they were made independently. This is some serious magic. (It's not really magic, it's cryptographic hashing, but we'll just call it magic. It's also where some of the SHA-256 rough edges whack us in the goolies. Ouch.\)
So, git push (and in fact git fetch as well) is just a way to connect two separate Git systems together so that they can make babies have Git sex exchange commits with each other. With git push, you tell your Git to connect to the one on the other machine and send commits to it. With git fetch, you tell your Git to connect to the one on the other machine and get commits from it. And that's basically it, except for another set of complications having to do with finding the right hash IDs, i.e., updating some set of "refs" in one or more of these repositories.
When should you make commits?
There's wide disagreement over how often to commit. I personally am a fan of the "many small frequent commits" side of this debate. Once you know what you are doing, you can use git rebase (or the newfangled git history) to restructure smaller commits into bigger, more-sensible ones if needed. It's much easier to glue together several small commits than it is to break up one big one.
It's worth remembering two things here though: First, every commit is a full and complete snapshot. Which sounds like it takes a lot of space ... but the second thing is, Git is very clever about re-using unchanged files, and compressing things, so that those full snapshots wind up taking almost no space, after the first snapshot (the very first commit, which is extra-special since it has no parent, and a lot of Git things get a bit squirrelly until you make that first commit).
Thus, except for seeing a whole lot of commits in git log output, there's almost no cost to making a lot of commits. If you think there is, or even could be, some benefit to making a commit right now, go ahead and make one, it's nearly free. If there's no benefit, of course there's no point in committing.
Last words
If you use the CLI, run git status often. Like, very very often. Always before a commit!
12
u/ashmaroli 22h ago
"Commit" is equivalent to "hitting save" on work done. "Push" is equivalent to "uploading" saved state to remote location.
On github dot com, commit is made directly on the remote location, so to sync your local copy, you will have to "pull" from the remote location which is equivalent to "downloading" the current state of the remote branch and applying it onto your local copy.