
Helloooo! I am Moose! They/Them/He/Him I am a embedded software engineer with autism, depression and anxiaty ( Wooo! ). I post about... whatever I want... software things, mental health things... whatever I feel like Feel very wellcome to send me asks about... anything that strikes your fancy :3
266 posts
A Beginners Guide To GIT:Part 2 - Concepts And Terms
A beginners guide to GIT: Part 2 - Concepts and terms
Table of content: Part 1: What is GIT? Why should I care?
Part 2: Definitions of terms and concepts

Part 3: How to learn GIT after (or instead of ) this guide.
Part 4: How to use GIT as 1 person

Part 5: How to use GIT as a group.

Now, a few (I PROMISE only a few!) concepts that are needed for being able to talk and read about GIT.
Just to be difficult, several of these have multiple names (Plø!)
GIT refers to its commands as "porcelain" commands (user friendly and clean) and "plumbing" commands (Not so user friendly, dirty). Yes. We are starting out with references to toilets :p
The workspace/working tree is all the files and folders you would have if you did not use GIT. It is folders, codefiles, headers, and build system files. All the good stuff we want to work on.
A repository is technically the hidden folder called “.git”. It is all the files GIT uses to keep track of your files and their history, and which enables you to do all the git things to the files in the working tree. You do NOT have to interact with these directly. Just know they are here ( Sometimes people refer to the working tree AND the repository together as “The repository”. Because we work hard on making life harder and more confusing than it needs to be)
The index/cache/staging area is a single, large, binary file in the .git. folder. It keeps track of the differences between last time you saved, and how the working tree is now. Every change, every new file, every file deleted.
Commit. To differentiate what GIT does from how you normally save files, we use the term “commit”. But it is just a save. Different commits are different saves. Easy peasy. Every commit, except the very first one is based on the commit before it. That is called the commits base.(This is the base that REBASE refers to).
The structure of GIT is actually very simple. It is a whole bunch of commits, and each commit knows the commit it came from (IE all commits except the first have a base). This makes a long chain. That's it. That is the entire idea
Staged files
So you now know that we can commit(save) and we have files that we change, but have not been committed. We need a name for files between those two. Files that we are getting ready to commit. All files that will be committed if you commit RIGHT NOW, are “staged for commit”.
HEAD. Because you can switch between different commits easily, we need a way to say “what commit are we looking at right now?”. That is HEAD.
HEAD can be “detached”. This basically means that the commit HEAD is pointing at, is NOT the latest commit. And while you CAN do work on a detached head, it gets messy and is not the smartest way to do it, so “detached head” also works as a bit of a warning.
(If you have ever worked with pointers, HEAD is simply a pointer to a commit)
If we make 3 commits, one after the other (which means HEAD is pointing at the last commit), then your commits could be represented like this:

Branches. These are commits that are done one after the other. You always have at least your starting branch (Usually named master or main). If you create new branches, then they start from a specific commit and can be merged into the original branch whenever you are done.
If we expand the previous example, make a branch from the first commit, and then merge it before the third commit and delete the branch, it could look something like this:
Make the branch and add to it:

Then merge it into the main branch and delete the new feature branch:

origin/upstream. This refers to what commit and branch a branch came from. In our example, the "New feature branch" would have the upstream/origin "Main branch" , "Initial commit".
-
hayacode liked this · 10 months ago
-
quietmarie liked this · 1 year ago
-
neuroglitch liked this · 1 year ago
-
animabelle58 liked this · 1 year ago
-
frog707 liked this · 1 year ago
More Posts from Moose-mousse
I just downloaded a program, as a git repository. It allowed you to have it work in several different ways. Which was achieved by simply using "git checkout" to check out whatever branch you want. I love it. That is so smart!
That is a very neat idea!
If you like things like that you might want to look into VHDL ( I learned that... some years ago, but have not touched it since ) or Verilog.
They are... programming languages for making logic gate logic.
You combine that with an FPGA, which is essentially a whole lot of NAND gates ( Which as I said, can represent any logic gate system ), and then you can make hardware... via software.
And yes, these essentially do things like your idea. Things that would take a CPU aaaaages to do, can be done very very fast. So you "just" have normal C code, but if it runs onto one of the problems it have hardware for, it uses the hardware.
This is also how graphics cards work, or just floating point operations!
It is insanely cool! :D
What is half-adder and full-adder combinational circuits?
So this question came up in the codeblr discord server, and I thought I would share my answer here too :3
First, a combinational circuit simply means a circuit where the outputs only depends on its input. ( combinational means "Combine" as in, combining the inputs to give some output )
It is a bit like a pure function. It is opposed to circuits like latches which remembers 1 bit. Their output depends on their inputs AND their state.
These circuits can be shown via their logic gates, or truth tables. I will explain using only words and the circuits, but you can look up the truth tablet for each of the circuits I talk about to help understand.

Ok, so an in the case of electronics is a circuit made with logic gates ( I... assume you know what they are... Otherwise ask and I can explain them too ) that adds 2 binary numbers, each which have only 1 character.
So one number is 1 or 0
And the other number is 1 or 0
So the possible outputs are are 0, 1 and 2.
Since you can only express from 0 to 1 with one binary number, and 0 to 3 with 2, we need to output 2 binary numbers to give the answer. So the output is 2 binary numbers
00 = 0
01 = 1
10 = 2
11 = 3 // This can never happen with a half adder. The max possible result is 2
Each character will be represented with a wire, and a wire is a 0 if it is low voltage (usually ground, or 0 volts) and a 1 if it is high voltage (Voltage depends. Can be 5 volts, 3.3, 12 or something else. )
BUT if you only use half adders, you can ONLY add 2 single character binary numbers together. Never more.
If you want to add more together, you need a full adder. This takes 3 single character binary numbers, and adds them and outputs a single 2 character number.
This means it have 3 inputs and 2 outputs.

We have 2 outputs because we need to give a result that is 0, 1, 2 or 3
Same binary as before, except now we CAN get a 11 (which is 3)
And we can chain full adders together to count as many inputs as we want.
So why ever use a half adder? Well, every logic gate cirquit can be made of NAND (Not and) gates, so we usually compare complexity in how many NAND gates it would take to make a circuit. More NAND gates needed means the circuit is slower and more expensive to make.
A half adder takes 5 NAND gates to make
A full adder takes 9 NAND gates.
So only use a full adder if you need one.
Geeks for Geeks have a page for each of the most normal basic cirquits:

I hope that made sense, and was useful :3
AHHHH!
Have to do a code review of a codebase I have had access to for 2 days... by copy... As in, I do not yet have access to the reposetory, as so cannot build the project... And so none of my tools work on it... Because massive anxiety an autism, and my supervisor asked if it was ok to have it today (Friday), rather than on Monday and so my mouth just said the words it figured the other person in the conversation wanted to hear... I do not have access to the internal communication tools either so... juuuust have to do it..... AHHHHHHHHH! I swear... I am so happy I went on tumblr, because I am just using the "Do it alone, do it scared" as a freaking mantra at this point...
(Also, sorry for not answering people or being super active... I am just focusing as much as I can on this internship)
A beginners guide to GIT: Part 5 - How to use GIT as a group.
Table of content: Part 1: What is GIT? Why should I care?
Part 2: Definitions of terms and concepts

Part 3: How to learn GIT after (or instead of ) this guide.
Part 4: How to use GIT as 1 person

Part 5: How to use GIT as a group.

For this, I will describe a workflow, called “feature branch workflow.” There are others that are simpler, and are sometimes better, but I will describe one that always works, for any amount of people, and most likely is what your future workplace uses.. And yes, it involves branching (which sounds scary, but it is not so bad.)
Why? Well because of 2 goals we have that somewhat clash.
1: To use GIT in a way that is easy on ourselves and will give us all the benefits of GIT. This means committing often. Pretty much every time we have made a change, and we can compile.
2: We want to sync our work with our fellow workers. But this takes effort every time we do it because we might have made changes that clashes with changes someone else have made.
(Notice though that this is not a problem originating in GIT. This is a problem that comes from people working together on the same thing. GIT just makes it easy to spot the problems and describe them in an accurate way.)
We alleviate this by only syncing up when we have made a larger chunk of self contained work. Usually we use the term "feature" for this. And they can be quite small (For example 4 commits, making a "Return to previous page" button ) or large (For example, 38 commits, which also used branches, to implement a GUI on top of the backend code we have made).
It is best to make features as small as you can, so that a feature branch does not end up being an entirely different sister project to the main branch.
The first thing we do is declare the main/master branch holy. Just like any branch, it must always compile, but now we add " May only have fully realized features". It must ALWAYS be ready to be shown to the customer/your boss/your adviser/your teacher.
So when we want to do some work, we coordinate it with our teammates so people are not working on the same thing, and thus wasting their time. ( This can be done with tickets, verbally at meetings, in group chats. Whichever fits your team )
Then we make a branch with its base at the tip of the main/master branch. We then do work, commit and push every commit onto that branch. This has all the benefits we had from working alone. We cannot get merge conflicts, as we are the only one working on this branch.
So let us show how this works! For this example I have set up a remote repository on bitbucket containing only a standard README that I have not written in at all., I then cloned it down in 2 different directories. Each of which I have opened with a console. This is how I will represent multiple people:

So first, we show off one person making a change, and the other getting it. So I add a main.c file in there, add it so it is staged for commit, and then commit it:

And if we write git status, we can see that we are 1 commit ahead of the remote repository:

We then push our commits to the remote repository:

The other user can now use git fetch (Which gets the latest information from the remote repository, but does not change anything):

We then pull the latest update from the remote repository with git pull:

This is the simple way to work. But of course, if we have changed the same file, we will get a merge conflict.
As we talked about, we will minimize those by using branches. So we will say that each of these two people now will work on a different feature. Each of which will be a function that prints something. And each will be in another c file, with a header. We will do this with branching. We want to make a branch, and then switch to it. Switching to branches is called “checkout”. We can do both in one step by checking out a branch that does not exist, with the option -b (You can as always read about checkout, by writing “git help checkout”)
git checkout -b My_Spiffy_Feature
When we then write git status, we can see that we are on the new branch:

I then add the new files. with the new function in, and we want test that they work by calling the function in main:

We then compile our program (which gets default name a.out) and run it:

It works! Great, time to commit. We add the new files, BUT NOT main.c or a.out . They were just for testing, and is otherwise not related to our feature.

And we then push to the remote repository:

As you can see, git complained, because while we have created our branch, we had not really configured it yet (Specifically, we never told git what branch this new branch should originate from from. We just created it out in the void). But GIT TELLS you what to do. So I simply wrote the recommended command, and bam, branch is working as we want it to
I update the new feature file, just so we have more than one commit. I add the changes, commit and push again:

Now that our feature is done, we want to merge the branch into the master branch.
To showcase something, I will first have the other person make a change to main, add, commit and push it:

The first person will now merge their spiffy new feature in. They do that by switching to the master branch with git checkout:

We see that we are behind 1 commit, so we pull.

But horror! Since we have the unstaged changes, we cannot pull, since we changed main.c to tests our new feature, AND the other person have changed main, those two cannot exist at the same time. So what do we do? Well, in this case, we are ok with our tiny test in main.c being lost. So we remove it like so:

Notice how EVERYTHING I did here, was just read what GIT said was the problem, then write git status, and do the actions that GIT tells me I can do, which solves the problem. Ok, now we have the latest update of the master branch. Time to merge our feature in:

This time I did not use the -m feature (Because I forgot) so I just used the external program to write the commit message.
And if we write git log, we can see every single one of the commits. Both in the branch, and in the master:

And if we want to get a bit of a graphical representation of what happened, we can use git log --graph:

Now, this is the simple way to do branching. You actually have full control over how exactly you want to merge your branch in. In this case, the two commits of the branch was added AFTER the commit on master. But we COULD have merged the branch in so that the two commits on the spiffy function was done BEFORE the changes on master. When you are still starting out, do not worry about this. But that is the workflow. You create a branch, you work on your feature in it, where you cannot get in the way of anyone else. When your feature is done, you merge it into the master. This way, the master was always ready to show to your teacher/boss, and did not have half implemented things that you would have to explain should be ignored at any point.
Half of the benefit of the feature branch workflow is that it minimizes the chance for merge conflicts. For them to happen, 1 group would have to go to the master branch and pull. AFTER they pulled, but before they managed to merge their branch in, another group must pull from master, and merged their feature in.
Unlikely.
But let us talk about merge conflicts.
Are those not horrible things that break everything?
No. Merge conflicts simply means GIT could not figure out how to merge something, and so a human will have to do it for it. GIT is nice, and shows you exactly where the problem is, and how to solve it. Let us create a merge conflict. The first person adds in the function that uses their new spiffy feature after the hello world prinf, stages the changes and commits them. But do not yet push

The other person creates 2 more printf statements in main, stages the changes for commit, and commits them:

Now we have 2 commits, that both changes main.c How should these two be merged? Should the spiffy feature be called before or after the newly added prinf lines? GIT cannot know this, and so will tell the humans to do it. And the job falls to whoever wanted to push in a change that creates the merge conflict. In our example, I will have the second person, who added the extra printf lines push first:

And now the first person with their spiffy feature pushes, and:

It fails... But we are fine. Nothing actually happened here. The remote is still fine, and we locally are still fine. But we have to figure out how to fix this. When in doubt, use git fetch to get all the info but change nothing, and then git status:

(By the way, I made an honest mistake here, and did not push the branch changes after I merged. But I am not really in trouble, because GIT saved me! :D) And as we can see, GIT is once again telling us what to do. Great!

And we are now at the place where we need to decide what to do. While you are still new, I recommend the default strategy. So we do as GIT tells us to:

And now, FINALLY, we have our merge error. But notice that we only got it this way, because we asked for it. So… what does that mean? Git status to the rescue once more!

As expected, the problem is in main.c Let us check out what is in that file:

We have our changes first, then a separation, and then the other changes. And fixing it is piss easy. We remove the lines GIT inserted to tell us where the conflict was, and put the code in order. WE decide if the spiffy feature should be put before, after or in the middle of the two printf statements. I decide to put them in the middle like so:

Merging the two versions together, is in of itself, a change to the code. So we will now do what we always do when we have made changes. Add the files that we changed, and make a commit, and then push:

We have now resolved the merge conflict.
Notice how the problems that we ran into were not GIT problems. We ran into issues that ALWAYS come up when multiple people are working on the same project. But GIT made it really clear what the issues were, and forced us to deal with them in a smart way! :D
A beginners guide to GIT: Part 3 - How to learn GIT after (or instead of ) this guide
Table of content: Part 1: What is GIT? Why should I care?
Part 2: Definitions of terms and concepts

Part 3: How to learn GIT after (or instead of ) this guide.
Part 4: How to use GIT as 1 person

Part 5: How to use GIT as a group.

First of all, GIT have a website:
And besides downloading GIT if you do not already have it, it has THE GIT book. It is honestly very good and contains quite a few translations
Second, GIT is one of the old pieces of tech. This means that it is open source, free, and that it contains its own documentation and guides.
If you are ever stuck, or confused about something in GIT, you can use the help command.
Simply writing
git help
Shows you the porcelain commands, and tells you that adding the option -a like so:
git help -a
gives you ALL commands
and the option -g gives you all the guides the manual have, like so
git help -g
If you give help another command,, it will bring you to the manual page for that command
for example, someone on the internet told you to write
git help reset --hard
and you want to know what that means before running it? Write
git help reset
And you will be shown the manual page for “reset”. Including what --hard does. (To understand the manual, you need to understand the concepts and terms from part 2.)
If you want more visual explanations, Atlassian's guides are public and also quite good (But , remember. Atlassian uses Bitbucket. Bitbucket is 99% GIT, but can still have tiny differences)