When you're on a branch, and you commit, the branch is updated to that new commit. So it's a pointer to a place, and the pointer moves (in the sense of changing to point to a new place automatically).
README edits are not a file(!) or a directory but a thing that you're doing
when I finished editing the README, I deleted the branch
since it wasn't needed any more
it was like a bit of scaffolding to make it safe to build something new onto the directory structure
I am thinking what I should possibly do is, instead of having a directory TO-TEST which is a cumbersome way of organising things, I should have a branch for every recipe that needs testing (one of your suggestions). When the testing is done, the branch for that recipe can be merged into the master branch and deleted. And that's how I'll know that the recipe needs work, because there's a branch for it.
@Zanna Yes, this is a common way to use branches in Git (though not the only purpose of them of course). It works well because Git branches are lightweight--they don't duplicate commits, they just refer to their tips. In some other version control systems, especially the older ones, branching is a big deal, and involves making a copy of everything.
Also, in many version control systems, the diffs between files between successive commits are stored. In git, each commit is instead a snapshot of a state of the repository. This takes up somewhat less space than you might think, though, because each version of each file is stored only once: what a commit really contains is the hash of each file in it, and the blob (the data of the file) is stored only once per hash.
Did you try cloning your hello-world repo, making local changes, and pushing those changes?
One reason is that I'm just more used to this because it use it to clone from servers I control which don't offer HTTPS cloning, so I already have the SSH analogue of credential caching set up.
But I suggest setting that up and using it nonetheless. I think it's good to not have to do password-based authentication (that is, to use key-based authentication).
@EliahKagan I also find that ssh-agent is highly flexible, because you can use it through a program like seahorse or (what I usually use) keychain. With keychain, you enter your passphrase in one sessions, and the key is available without further authentication in other concurrently running or subsequently started sessions.
This works well for me because I often use a machine via SSH or on a virtual console, either separately from or in addition to (or in the total absence of) its GUI. But I think many users get what they need with seahorse. I don't know if Ubuntu MATE comes with seahorse integration that works seamlessly as it does with GNOME or not.
@Zanna Possibly.
I mean, in general, key-based authentication is more secure than password-based authentication. But there are other considerations; I wouldn't want to make a pronouncement about practical security without a broader picture.
Also, because I use SSH so much more often for Git remotes than HTTPS, I'm reluctant to make statements about what HTTPS can't do or doesn't do well, because I might just be unaware of how people do it.
@Zanna Yes, you should add your public key. If you don't have an SSH key pair, you should generate one with ssh-keygen. After you add your public key, you should verify GitHub's key fingerprint before proceeding with a connection. (I suggest ssh-ing in first with ssh to do that.)
Of course I don't mean to imply extreme absurdities like "No one should ever say X is better than Y." But I don't feel confident in claiming that HTTPS authentication for repos is inherently inferior to SSH authentication.
@Zanna I think the counterargument is that one ends up comparing a language in which one is proficient (or, in Stroustrup's case, an expert) to other languages whether one wishes to or not. So I'm actually not sure if I agree with his conclusion. But I think the considerations he's articulated for why comparisons between programming languages are often not illuminating are correct and important.
@Zanna Did you generate an SSH key pair but not know where the files for it are?
அக். is October.... 2017. That would be when I last did a clean installation. So I would have lost the keys then. Hmm. I don't know how we are supposed to manage these things at all
You can back up the generated key files in ~/.ssh, or the whole directory.
As for generating a new key when you don't have one, run ssh-keygen.
You should put in a good passphrase.
@EliahKagan Backups of your private key should be secure and private, though. Anyone with your private key can trivially impersonate you to any person or service who thinks the key is still good.
@EliahKagan The passphrase is used to encrypt your private key on your disk.
You should make sure the GitHub server's key fingerprint matches the fingerprint shown on that linked page (and that the page is HTTPS with no scary browser warnings).
That shows two fingerprints, but if the one you see isn't the SHA256 one, I'd be... intrigued.
One way to compare them reliably is to copy the fingerprint in your terminal and paste it into a Ctrl+F search box in the browser (and make sure it highlights the key shown there as a full match).
You should not attempt to "eyeball" it. :)
Also, make sure not to accidentally copy the fingerprint from the web page and then search the web page for the fingerprint copied from it. :)
(I've seen these things done.)
(Not specifically with that GitHub page.)
@EliahKagan To expand on that, since each testing recipe is on its own branch in the setup you described, at most one testing recipe will be in the working tree at any given time. So if you wanted to work on more than one at a time on the same machine, you'd have to have two local repositories on the same machine syncing to the same remote, with different branches checked out.
In practice I suspect you'd end up making a separate testing directory somewhere and copying files back and forth between it and the repository or something. If so, it would be better to just have that directory in the repository and not have to copy.
You might actually not want to use any feature branches as part of the general workflow for the testing recipes. Even if you don't, you might still sometimes use branches to work on changes to individual recipes and merge them back in.
I'm not sure what you'll want to do, those are just my thoughts.
The dialog box has a checkbox that lets you have it keep the decrypted private key in memory for the rest of the graphical desktop session. You might want to use that. :)
So, each time you perform a remote operation in your repository, it has to authenticate (this is the case whether you use HTTPS or SSH). But it will authenticate automatically using your SSH key, now.
(Just with a different key "comment" than ek@Ilex and possibly a different border style.)
If so, then whether or not you check the box, it will remember it for the rest of the graphical login session.
If you do check the box, it will effectively remember it in all future graphical login sessions as well.
I believe the way this works is that it stores a re-encrypted copy of the decrypted private key, encrypting that copy based on your login password or an authentication token generated from your password.
It's being taken care of by gnome-keyring-daemon, even on MATE (at least on my system).
If you use a non-graphical login on the machine, though, then it won't work and you'll have to enter your passphrase. If that's a significant use case for you then you might want to use keychain.
@EliahKagan Or maybe it stores the passphrase encrypted based on your login password. I don't know.
@Zanna So, now that that's set up, you should be able to clone your repo via SSH, and you shouldn't have to enter any password or passphrase this time.
I don't know the situation. But... If you know they're excessively aggressive...
Or is the issue that you're concerned it may be excessive but think it's probably okay but are still worried?
(I should stop asking questions about this.)
So you're in the cloned repository?
git log shows the history you expect?
You can see all your local branches, including (and at this point, only) the one that was created automatically by the clone, by running git branch as you have been doing.
But you can also pass the -a option to git branch to see remote branches too.
git branch -a
If you run:
git remote
That shows all your remotes. (A remote may have more than one branch on it of course.)
You can display detailed information about a remote by passing the name of the remote to git remote show, for example:
git remote show origin
That also connects to the remote to get current information (unless you pass the -n option to tell it not to).
You'll notice that you have remote tracking branches set up (or at least one, anyway). These are the additional branches listed in the output of git branch -a. Usually I will call these "remote branches," but it is important to understand that they are copies of branches on the remote repository. They store the the last known state of those branches on the actual remote (including all the commits of course).
Those branches actually exist in your local Git repository and, as such, they can become out of date. You can also have fewer of them than there are on the remote, if branches are created on the remote before you fetch from the remote, or more, if branches are deleted on the remote.
An example of such a branch that you probably have is origin/master.
The main things you do with them are to fetch from them and push to them. Both these operations actually communicate with the actual remote repository.
BRB in a few minutes. In the mean time git help fetch may interest you.
I'm back.
Running git fetch is one way to fetch from a remote repository.
This updates the commits in your remote-tracking branch.
Btw, I feel like I should check if I am using the term "remote tracking branch" correctly; it might be an overcorrection.
I think I've been using it correctly but I'm just gonna say "remote branch" for stuff like origin/master (which is what I did before I tried to be all accurate and whatnot).
The Pro Git book mentions:
Tracking branches are local branches that have a direct relationship to a remote branch
Not exactly. The SO question "Having a hard time understanding git-fetch" includes:
There's no such concept of local tracking branches, only remote tracking branches.
So ...
@EliahKagan This is like how you might think of text you read on a website as being on the web.
Even though everything you see on that website has been downloaded to your computer (and usually even saved to disk!) and that's where you're seeing it.
If the contents of the website change, you won't see the changes unless some mechanism updates your local copy with information from the website.
I had thought up that analogy because a friend of mine (a different one from the one with >) was having trouble understanding what git fetch did, but I have not actually used the analogy before now.
You might also want to save a website to your computer.
@EliahKagan Even though... it already probably is, in your browser's cache!
@Zanna Okay.
@EliahKagan But the browser cache is supposed to have whatever is known about what content the web server is providing. Conceptually it is as though you don't have a copy even though you do.
@EliahKagan This analogy is not exact here because it is possible for a web browser to cache in RAM only, and also because the cache can't be relied on the same way as most files you've saved manually, because browser caches, like caches in general, are subject to invalidation, where whatever stuff in the cache seems least valuable to retain (based on some cache invalidation policy) is removed automatically when room in the cache is needed for other stuff.
In contrast, information stored for branches like origin/master in your .git folder does not get destroyed automatically. Nonetheless, the analogy partly holds in that it is neither supported nor (pardon the pun) remotely a good idea to attempt to change its contents.
I am inclined to reply to that with a resounding "yes, of course they are"... but what do you mean by reliable?
Like, the remote can totally change, especially by having more commits than there were before, and branches pointing to later commits that didn't exist before. When you examine a branch like origin/master, you're examining your local version of the branch, which may well be out of date.
Fetching makes such branches no longer out of date.
zanna@toaster:~/playground/hello-world$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean
@EliahKagan it was a satisfying delay. I could tell whatever was supposed to happen was happening
The information it shows may become stale; unlike git fetch whose entire point is to bring your repository's knowledge of branches on a remote completely up to date including all new commits, and also unlike git remote show ... (where ... is some remote), which updates basic information about the remote but does not download new commits, running git status does not communicate with a remote repository, it just tells some information that is locally known.
@Zanna Can you go ahead and make a change on the remote? (You can do this through the GitHub interface, as you did before.)
So, right now, your local branch master is connected to origin/master. This is to say that master set up to synchronize with origin/master. You'll see what that actually means soon.
I had been thinking you'd make a change on master which would show that. But there's no need to see that first. You created a new remote branch, which is an opportunity to see how to bring that relationship -- between a local branch and a remote branch -- into being.
One way of bringing that relationship into being, you've seen already. You clone the repository and master was connected to origin/master. Specifically the way that was automatically achieved was that the master branch was checked out for you automatically (by default, git clone checks out a branch, after cloning a repo).
So you can probably guess that a way to set this relationship up yourself is to check out the branch yourself. And you'd be right! The is the most common way it's done.
Try:
git checkout short
Note that you're checking out short, the local branch that doesn't yet exists but will be created automatically, and connected to origin/short, by the checkout.
zanna@toaster:~/playground/hello-world$ git status
On branch short
Your branch is up-to-date with 'origin/short'.
nothing to commit, working tree clean
zanna@toaster:~/playground/hello-world$ git fetch
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From github.com/ZannaStar/hello-world
0c4612c..43b17b8 short -> origin/short
It wouldn't quite be redundant, in that it would do another fetch, and if there had been changes between the original fetch and when you ran git pull, you may not have expected them.
zanna@toaster:~/playground/hello-world$ git merge
Updating 0c4612c..43b17b8
Fast-forward
list | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
zanna@toaster:~/playground/hello-world$ git status
On branch short
Your branch is up-to-date with 'origin/short'.
nothing to commit, working tree clean
When you want to fetch and merge and you don't want to bother checking what's fetched first, just run git pull. When you want to fetch, check, and then (presumably) merge, run git fetch, do whatever you want to do (which might even be just inspecting the message), then run git merge (or git merge with an argument if you prefer). Either of those is totally fine. Some people say it's better to fetch and merge separately but most of the time I just run git pull, as do many people.
It's specifically running git fetch followed by git pull that should not usually be done, because git pull doesn't quite always do the same thing as git merge even after a fetch, in that git pull may fetch additional changes and merge them unexpectedly.
It's only using git pull when you mean git merge that I'm trying to discourage. git pull instead of git fetch followed by git merge may well be what you want to do.
Now, with that said, it's common to have an editor or IDE with git integration, or a graphical git client like GitKraken, to fetch automatically, like every minute or so.
So you could fetch, then be about to merge, and that fetches again, and your merge merges additional commits.
Nonetheless, I wanted to clearly convey what git pull does and why people sometimes fetch and merge separately. Plus, you will typically know if you have automatic fetching happening.
Personally, I always enable automatic fetching when it's convenient to do so.
Not when just using git from the command like, but like, in vscode, which integrates with git automatically (by running git commands behind the scenes; it's not its own client, per se), I have it fetch automatically.
So if you do run git pull now, no changes will be made because there's nothing to fetch, and thus nothing new to merge.
But I still suggest doing that.
Then I suggest making another change through the GitHub interface and running git pull.
@EliahKagan I merged the short branch and deleted it
$ git pull
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (1/1), done.
From github.com/ZannaStar/hello-world
9b76d2b..294c8e8 master -> origin/master
Your configuration specifies to merge with the ref 'refs/heads/short'
from the remote, but no such ref was fetched.
@Zanna That was a somewhat more complex change than I had in mind for seeing how git pull works. :) It works though, in that if you check out your local master branch, you'll be able to see the changes in it, even without running git merge.
@Zanna That's the normal color scheme.
@Zanna That still lists origin/short even though the remote doesn't have it. And you still have a local short branch. You probably don't want origin/short anymore, since it doesn't actually exist on the remote. You possibly don't want the local short branch either.
This is normal. You can prune the remote branch in your local repository. It's a good idea to pass --dry-run first to see what would be pruned.
git remote prune origin --dry-run
If that looks good you can drop the --dry-run option.
Then if you want to delete the local branch, you can do it by checking out some other ranch (so you're not trying to delete the branch you're on) and then using the -d option to git branch, with the branch you want to delete as an operand. The more dangerous -D option should not be needed because the branch is fully merged.
This blog post is a good "cheat sheet" for this situation. (Well, fairly good. It relies overly on images.)
$ git status
On branch master
Your branch is behind 'origin/master' by 3 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
nothing to commit, working tree clean
...to see how git diff works to see differences that haven't been merged from a remote
I emphasize that this is not really helping with getting rid of short safely, just something I had meant to show you with short before you deleted it on GitHub that I can now show you with master instead.
(You can probably also even do it with short since you do still have origin/short, but it's not up to date--to be up to date, origin/short in your local repo would have to... not exist anymore. :) )
@EliahKagan Btw I should absolutely not have said that after running git pull while on short you would get changes merged from origin/master into master. That's not how git pull works, ever. When I figure out what I was thinking, I'll let you know.
@EliahKagan I figured out what I was thinking. Originally I thought, for some reason, that you were onmaster locally. Then when I found out you weren't, I stapled some deep and profound wrongness into my message. I was thinking about the situation where you were on master, pulled but didn't examine the result, changed branches, deleted the short branch remotely, fetched either as part of a pull or otherwise, and then were interested in the master branch. But that wasn't your situation.
Yes. I'm not frustrated with myself for most of my errors or mispredictions so far. :) I am only trying to call attention to (and also apologize) for the inadvertent claim that git pull merges into multiple branches. It doesn't do that and it's a source of massive confusion because people who've just started using git often assumes it does. Amplifying that confusion would be very bad.
Part of the confusion, in general, is that you can run git pull --all, but that also does not merge anything but the current branch. (What's going on with that is that git fetch --all fetches from all remotes rather than just the default remote, which is useful because you can have multiple remote set up for the same repository. Running git pull --all causes git fetch --all to be run for the fetch, but it still just merges to the current branch after the fetch.)
@EliahKagan earlier we were using this command, but I forgot the details of the different ways we can use it. I sort of half guessed that we can compare some branch to the one we're on by passing the name of some branch as an argument, so this is what I did and what I got
@EliahKagan Often git diff is useful with arguments, to see what changed between specific commits (or between a specific commit and the current index, if you only pass one argument). But it's also used to see the difference between the current state of your working tree and your index.
@EliahKagan There is some terminal program (for some OS) that actually warns when you attempt a paste that seems like it's a mistake. It examines the contents of what's being pasted, possibly only for length and number of lines. I don't remember what that is though!
When you get back (or whenever), you can run git merge on master to bring it up to date with origin/master (with the information that your local repo currently has for that).
Or run git pull on master to pull anything new, though I don't think there's anything not fetched.
Or run git fetch to fetch anything new (though I don't think there's anything) on master followed by git merge.
After that, you can see what the deal is with short by running:
git diff master short
I don't know what order you'd want to specify the branches in, but I'd do it that way because the idea is to see what's new in short that's not in master, if anything, since that would be an indication that you shouldn't just delete short.
Of course, you see the same information with git diff master short as with git diff short master, but the +es and -es are reverse. I think git diff master short is a more intuitive way to look for actual file contents that may be in short but not in master.
Alternatively, maybe git log (with or without arguments) will show that they're on the same commit, or otherwise shed light on the situation.